[ACCEPTED]-C++ allocating dynamic memory in a function - newbie question-pointers

Accepted answer
Score: 19

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

What you want 2 is a reference:

void func(char *& cp)

This will alias cp to be the 1 parameter passed in.

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

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

Score: 6

The parameter cp is a local variable of 7 the function - changing it does not alter 6 anything outside the function. A better 5 way to write the function is:

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

And not to 4 do directly with your question, but you 3 should probably be using std::string and 2 std::vector rather than dynamically allocated 1 arrays.

Score: 1

You're passing in cbuf, not cp.

0

Score: 1

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

Score: 1

Although references are wonderful in offering 12 an intuitive abstraction, enhanced further 11 by C++11 rvalue references to allow function 10 chaining (and other esoteric coding), it 9 is arguable that they provide any safety 8 (viz why is a reference considered safer than a pointer) There are instances where it is 7 better to resolve the above with a pointer 6 to pointer function argument. Specifically 5 when there is the need to maintain a similar 4 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 3 disposal of memory resources out of the 2 scope of the instatiating function disobeys 1 RAII.

Score: 0

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

char* func();

or 14 void func(char*& p);

which will solve your immediate problem.

There 13 is, however, a maintenance problem. In either 12 case, func returns a pointer. What is not 11 clear to the user of func is that returned 10 pointer will have to be deleted. For this 9 reason, generally avoid this construct unless 8 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 7 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 6 especially, it might be 100% necessary to 5 have some sort function to create the array. Therefore 4 in C programming you can replace the destructor 3 with a CreateCBuf and DestroyCBuf function. In this way the user 2 of your library will know that the buffer 1 returned needs to be destroyed.

More Related questions