Reputation: 3389
I have a CGFloat pointer in my header that is used to point at a CGFloat array. I declare it like that: CGFloat* pointer;
. In the initialization I try to set the pointer using this code:
CGFloat newArray[2] = {
0.0f, 1.0f,
};
pointer = newArray;
This "actually" works. I don't get any compiler errors and stuff. When i print the second value of the array right after setting the pointer with this code: printf("%f", pointer[1]);
I get the right result (1.000000). However, when I print the second value of the array in the method called next i get 0.000000 which means that the pointer doesn't point at the array anymore.
I've got two questions. How do I fix this problem and why does the pointer work right after setting it but "forgets" its value again?
Upvotes: 0
Views: 241
Reputation: 162722
CGFloat newArray[2] = {
0.0f, 1.0f,
};
Array indices start at 0. pointer[1]
prints the second element in the array, not the first. pointer[2]
is off the end of the array.
CGFloat newArray[2] = {0,0};
newArray[0]; // this is the 1st item
newArray[1]; // this is the 2nd item
newArray[2]; // this is nonsense.
Note that if you try to pass newArray
somewhere with the intention of using it later, it'll be badness. newArray
is on the stack and will be destroyed when the scope is destroyed.
If you want a function that returns an array of two floats, you'd do:
CGFloat *two_of_these() {
CGFloat *newArray = malloc(2 * sizeof(CGFLoat));
newArray[0] = 42.0;
newArray[1] = 59.4;
return newArray;
}
Just make sure and call free
on that return value later. Note that it is exceedingly rare to allocate something so small. Typically, it'll be a structure that is returned directly. See CGPoint
, CGRect
, NSRange
, etc....
Upvotes: 1
Reputation: 3919
Larcus, newArray
is being initialized on the stack in a non-global scope. The memory for your array is allocated in the one particular scope. When you call another method then CGFloat* pointer
is no longer pointing to newArray
because newArray
may or may not exist at this point. If the second method isn't being called from within the first scope then strictly newArray
will have been deallocated from its original stack frame. Instead, assign pointer like this pointer = new CGFloat[2]; pointer[0] = 0.0; pointer[1] = 1.0;
I think this is the only way to guarantee that the memory you are allocating will be allocated on the heap and not randomly overwritten or un-scoped.
See Wikipedia on Dangling Pointers
The punchline is that if you do not allocate memory using either malloc
or new
and assign that memory to a pointer, the state of that memory will be undefined. Only malloc
and new
can initialize memory in a way that will persist permanently across all scopes of your application.
Upvotes: 1
Reputation: 35235
In general seems like lifetime of the newArray
is shorter then the pointer
, so the pointer becomes invalid on a second call. To solve this, you need to move initialisation var, so it will have same lifetime as pointer
. The other solution would be memory allocation at runtime (using malloc
etc.), and free it after usage.
Upvotes: 0
Reputation: 5597
I think you get array indices from bbum's answer. 'pointer' points to an address. You set it to the address of newArray, but newArray isn't guaranteed to be around when your second method is called.
Upvotes: 0