C++ C++;在函数-新手问题中分配动态内存

C++ C++;在函数-新手问题中分配动态内存,c++,memory,function,dynamic,pointers,C++,Memory,Function,Dynamic,Pointers,我正在调查内存泄漏,据我所见,问题如下: int main(){ char *cp = 0; func(cp); //code delete[] cp; } void func(char *cp){ cp = new char[100]; } 在//code注释中,我希望cp指向分配的内存,但它仍然是一个空指针,这意味着我从未删除内存。我在写什么?参数cp是函数的局部变量-更改它不会改变函数之外的任何内容。编写函数的更好方法是: char * func

我正在调查内存泄漏,据我所见,问题如下:

int main(){
    char *cp = 0;
    func(cp);
    //code
    delete[] cp;
}

void func(char *cp){
    cp = new char[100];
}

在//code注释中,我希望cp指向分配的内存,但它仍然是一个空指针,这意味着我从未删除内存。我在写什么?

参数cp是函数的局部变量-更改它不会改变函数之外的任何内容。编写函数的更好方法是:

char * func(){
    return new char[100];
}

不要直接回答您的问题,但您可能应该使用std::string和std::vector,而不是动态分配的数组。

您正在分配
cp
分配内存的值。然而,这是堆栈上的一个变量:main中
cp
的副本
cp
是您所在函数的本地值

您需要的是参考资料:

void func(char *& cp)

这将别名
cp
作为传入的参数。

您传入的是
cbuf
,而不是
cp

void func(char *cp){
    cp = new char[100];
}

在这个函数中,char*cp是一个“指针通过复制”这意味着它们指向相同的内存地址,但它们不是相同的指针。当您更改内部指针,使其指向其他位置时,传递的原始指针将一直指向0。

该函数仅更改
cp
的副本。请使用参考资料。

正如GMan和Neil所提到的,为了工作,您必须将func更改为:

char*func()

void func(char*&p)

这将解决你眼前的问题

然而,存在一个维护问题。在这两种情况下,func都返回一个指针。func用户不清楚的是,返回的指针必须删除。因此,除非100%必要,否则通常避免这种构造。而是:

  • 帮助用户分配可传递给func的正确内存量
  • 使用对象存储分配的内存。然后,对象可以在销毁字符数组时删除该字符数组
  • <对于C++代码,我建议:

    
    class CBuf
    {
    public
        CBuf() 
        {
            iBuf = new char[100];
        }
        ~CBuf
        {
            delete[] iBuf;
        }
        char* func()
        {
            //do stuff;
            return iBuf;
        }
    private:
        char* iBuf;
    };
    
    int main()
        {
        CBuf cb;
        char* mychar = cb.func();
        //do stuff with character array
    
        //destructor gets called here because cb goes out of scope
        }
    

    然而,特别是在C编程中,可能100%需要使用某种排序函数来创建数组。因此,在C编程中,可以用
    CreateCBuf
    destroucCBUF
    函数替换析构函数。通过这种方式,库的用户将知道返回的缓冲区需要销毁。

    尽管引用提供了直观的抽象,并通过C++11右值引用进一步增强,以允许函数链接(和其他深奥的编码),但它们是否提供了任何安全性(即 在某些情况下,最好使用指针到指针函数参数来解决上述问题。 特别是当需要在ANSI C和C++中保持类似的代码库时。p>
    #include <iostream>
    
    using namespace std;
    
    void func(char ** cp) {
        *cp = new char[100];
        //do something useful
        (*cp)[0] = 'A';
    }
    
    void func(char *& cp) {
        cp = new char[100];
        //do something useful
        cp[0] = 'B';
    }
    
    int main(int argc, char** argv) {
        char * cp;
        //pointer to pointer
        func(&cp);
        cout << "Index 0 : " << cp[0] << '\n' << flush;
        delete[] cp; //remember to delete!!
        //pointer to ref
        func(cp);
        cout << "Index 0: " << cp[0] << '\n' << flush;
        delete[] cp;
        return 0;
    }
    
    #包括
    使用名称空间std;
    无效函数(字符**cp){
    *cp=新字符[100];
    //做些有用的事
    (*cp)[0]=“A”;
    }
    无效函数(字符*&cp){
    cp=新字符[100];
    //做些有用的事
    cp[0]=“B”;
    }
    int main(int argc,字符**argv){
    char*cp;
    //指针到指针
    func&cp;
    
    我能假设
    cbuf
    应该是
    cp
    吗?定位真实的代码怎么样。除非代码被剪切粘贴,否则你可能会添加错误。这只会让事情变得更困难,我们最终会解决像cbuf->cpSorry这样的剪切粘贴错误。关于这一点,我下次会记住。是的,cbuf应该是c即使他通过了CP,它也会指向0个//码,这也没关系,因为你也通过值传递。嗯,两个下票。我不特别在乎,但是其他人可能从知道这个答案的错误中受益。我看不到任何东西。如果你要指出一些类似C++的特性。另外,如果你打算使用那些特殊的功能,你可能想通过引用传递一个指向其中一个的指针来创建它,或者通过引用传递一个已经创建的指针来避免复制构造函数的惩罚……但是实际上,没有什么比这更重要的了用这个答案,指针没有复制构造函数。我指的是STD::String和STD::vector,当提到“C++的特性时,你说”。我把我的回答弄得一团糟,很抱歉,你有什么,我会加上“不要硬代码…”。剩下的是指“C++特性”。vector很好。它为您处理所有内存管理。OPs示例中的问题是所有权非常不明确。