C++ allocating dynamic memory in a function - newbie question

前端 未结 7 1582
借酒劲吻你
借酒劲吻你 2021-01-31 12:05

I\'m investigating a memory leak and from what I see, the problem looks like this:

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

voi         


        
相关标签:
7条回答
  • 2021-01-31 12:35

    The function is only changing a COPY of cp. Use a reference instead.

    0 讨论(0)
  • 2021-01-31 12:37

    Although references are wonderful in offering an intuitive abstraction, enhanced further by C++11 rvalue references to allow function chaining (and other esoteric coding), it is arguable that they provide any safety (viz why is a reference considered safer than a pointer) There are instances where it is better to resolve the above with a pointer to pointer function argument. Specifically when there is the need to maintain a similar codebase in ansi c and c++.

    #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;
    }
    

    Of course the disposal of memory resources out of the scope of the instatiating function disobeys RAII.

    0 讨论(0)
  • 2021-01-31 12:53

    You're passing in cbuf, not cp.

    0 讨论(0)
  • 2021-01-31 12:56

    As GMan and Neil mentioned, in order to work you will have to change func to:

    char* func();

    or void func(char*& p);

    which will solve your immediate problem.

    There is, however, a maintenance problem. In either case, func returns a pointer. What is not clear to the user of func is that returned pointer will have to be deleted. For this reason, generally avoid this construct unless 100% necessary. Rather:

    1. Help the user allocate the correct amount of memory which can then be passed to func
    2. Use an object to store the allocated memory. The object can then delete the character array when it is destructed.

    So for C++ code,I would recommend:

    
    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
        }
    

    However, in C programming especially, it might be 100% necessary to have some sort function to create the array. Therefore in C programming you can replace the destructor with a CreateCBuf and DestroyCBuf function. In this way the user of your library will know that the buffer returned needs to be destroyed.

    0 讨论(0)
  • 2021-01-31 13:00

    You are assigning cp the value of the allocated memory. However, that's a variable on the stack: a copy of the cp in main! cp is local to the function you're in.

    What you want is a reference:

    void func(char *& cp)
    

    This will alias cp to be the parameter passed in.

    0 讨论(0)
  • 2021-01-31 13:01
    void func(char *cp){
        cp = new char[100];
    }
    

    In this function, char *cp is a "pointer being passed by copy" what means that they are pointing to the same memory address but they are not the same pointer. When you change the pointer inside, making it to point to somewhere else, the original pointer that has been passed will keep pointing to 0.

    0 讨论(0)
提交回复
热议问题