Reputation: 4809
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
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
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.
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) {
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
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
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
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
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