tags:

views:

135

answers:

6

I am just starting to learn C and (of course) struggling with pointers :)

Given this snippet:

int *storage, *storage_p;
storage = malloc(sizeof(int[GROW_BY]));
storage_p = storage;
// do something with storage, using storage_p
free(storage);
storage = NULL;

Is it really necessary to have two variables declared to work with the malloc()'ed data? Is it good practice to create a storage and storage_p the way I did? If not, what would would be 'the way'?

+1  A: 

I would suggest not having copies of pointers around. It just increases the chance of having a dangling free pointer that you may accidentally use later, or an extra copy you may not mean to free, or an extra copy you may not mean to double-free. I don't personally see a need for storage_p here.

Gool 'ol:

int *storage = malloc(size_of_whatever);
storage[0] = do_something();
free(storage);
storage = NULL;

would be fine.

eruciform
+1  A: 

No, I don't see where you've gained anything by having both storage and storage_p. I'd normally just have one of them.

Jerry Coffin
A: 

That seems unnecessary to me. I'm not sure what the middle section might be, but I can't see any benefit to aliasing the pointers like that -- unless you're modifying storage_p (for example, incrementing it to iterate). In fact, having two aliased pointers could make it more difficult to keep track of the allocated memory.

Thom Smith
+2  A: 

I would only duplicate a pointer that was created by malloc for one reason: I want to modify it.

For example, If you were iterating through a character array you allocated with malloc, I would copy the pointer to a new variable to iterate through and leave the first one untouched.

Also when it comes to dynamic allocation, take a look at free lists, they simplify a lot:

http://en.wikipedia.org/wiki/Free_list

Bob Fincheimer
Thanks, I will look into them.
Dennis Haarbrink
+2  A: 

You will need a pointer that will hold the value returned by malloc(), so that you can free it later.

If what you plan on using storage_p for is going to change it value, then you are going to need two pointers.

However, I generally keep the pure initial pointer, and create new ones, ad hoc, as I need one.

int *storage = (int*) malloc(sizeof(int[GROW_BY])); 
// :
int* ptr = storage;
while (*ptr)
{
  // :
  ++ptr;
}
James Curran
That is exactly my case. I used `storage` in a loop (incrementing it) and when i invoked `free()` I got a segfault. I guess my description wasn't clear enough.. So to recap, normally you don't create a copy unless you have to modify the pointer. Is that correct?
Dennis Haarbrink
That is Correct.
James Curran
Thank you, those are some good pointers ;)
Dennis Haarbrink
+1  A: 

The reason you might want to do this is because after you do a few manipulations with storage, you may not remember what to free(). Having storage_p as a copy that you never modify helps prevent memory leaks because you can call free(storage_p) later regardless of what happened to storage. Whether this outweighs the disadvantages already mentioned depends on details of the situation.

An example:

int *storage;
storage = malloc(sizeof(int[GROW_BY]));
storage++;
free(storage); //SEGFAULT or MEMORY LEAK or OTHER BAD STUFF
storage = NULL;

vs

int *storage, *storage_p;
storage = malloc(sizeof(int[GROW_BY]));
storage_p = storage;
storage++;
free(storage_p);
storage_p=NULL;
storage = NULL;
Larry Wang