user550413
user550413

Reputation: 4809

How to allocate a memory to a given pointer to an array in C++

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.

Upvotes: 2

Views: 289

Answers (5)

pinxue
pinxue

Reputation: 1746

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).

Upvotes: 0

Filip Roséen
Filip Roséen

Reputation: 63797

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.

Upvotes: 3

Ernest Friedman-Hill
Ernest Friedman-Hill

Reputation: 81684

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

Upvotes: 1

Mike Seymour
Mike Seymour

Reputation: 254431

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.

Upvotes: 1

Björn Pollex
Björn Pollex

Reputation: 76788

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.

Upvotes: 7

Related Questions