2

I've tried to allocate a memory this way:

main:

X** a;
func(a);

func:

func(X** a){
   int size = 5;
   X* array = (X*)malloc(5*sizeof(X));
   //some writing to the array..
   a = &array;
}

If using the debugger I see that when I am in the function func everything is okay = i can write to the array and a really points to the array but the moment I am back to the main I something changes and I can't access the array through a (on the debugger it writes something like: Target request failed: Cannot access memory at address 0x909090c3 and so on).

Where is my mistake?

Note: It does compile but has a run-time problem if trying to access (print for example) the array in the main section.

Thanks.

user550413
  • 4,609
  • 4
  • 25
  • 26

5 Answers5

7

You have to change your main like this:

X* a;     // create an uninitialized pointer
func(&a); // pass the address of that pointer to the function

And inside your function, do this:

void func(X** a){
   int size = 5;
   X* array = (X*)malloc(5*sizeof(X));
   //some writing to the array..
   *a = array; // change the value of the pointer to point to the array
               // you allocated
}

Note that in C++ the way to go would be to use an std::vector<X>:

std::vector<X> func() {
    std::vector<X> buffer(5);
    // do stuff with buffer
    return buffer;
}

std::vector<X> foo = func();

This would create a new vector inside the function and return a copy of that vector to the caller. Note that the copy would be optimized away.

Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
3

You are changing the local copy of your variable a, it will not propagate to the outside of function (ie. the calling scope). Easiest solution to your problem is to pass a by reference, but you can also pass it using a pointer and dereferencing the pointer inside of your function.

See the below examples.


Using a reference

void func (X*& a) {
  X* array = (X*) malloc (5*sizeof(X));

  a = array;
}

...

  X* a;

  func (a);

The ampersand on the line below states that a is being passed by reference, ie. changing it inside the function will make the change propagate to parameter the caller used.

void func (X*& a) {

Using a pointer-to-pointer

This can be hard to comprehend if you are inexperienced when it comes to pointers, but we will make func take a pointer-to-pointer as it's parameter and pass in the address of variable a from main.

Upon dereferencing the pointer-to-pointer we can safely store away the information we want.

void func (X** pointer_to_a) {
  X* array = (X*) malloc (5*sizeof(X));

  *pointer_to_a = array;
}

...

 X * a;

 func (&a); // pass in address of a

NOTE

Since you are writing C++ (stated by question title and tag) you should not be using std::malloc, instead refer to operator new.

Filip Roséen - refp
  • 62,493
  • 20
  • 150
  • 196
1

You're setting the local pointer a to the address of the local pointer array, when you want to set the target of a to the value of array:

*a = array;

and call it as

X * a;
func(&a);

It would be less confusing to return the pointer (i.e. X * func()).

Also, you've tagged this C++ not C, so you shouldn't be using malloc; use the standard containers, or if they don't work for you, allocate using new and manage the memory with a smart pointer.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
1

In main, a is a pointer to a pointer. That means that two things have to exist: the block of memory, and a pointer pointing to it. Then a can point to that pointer. In your attempt, that middle pointer is being allocated on the stack of func, and when func returns, it's destroyed, so that's not going to work.

You could do this:

X* pa;
X** a = &pa;
func(a);

func(X** a){
   int size = 5;
   X* array = (X*)malloc(5*sizeof(X));
   //some writing to the array..
   *a = array;
}
Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
0

Think it over: a = &array; array is a local variable allocated on heap, &array will be junk when its scope is over (the function body).

pinxue
  • 1,736
  • 12
  • 17