5

I create a dynamic array in C with malloc, ie.:

myCharArray = (char *) malloc(16);

Now if I make a function like this and pass myCharArray to it:

reset(char * myCharArrayp)
{
    free(myCharArrayp);
}

will that work, or will I somehow only free the copy of the pointer to myCharArrayp and not the actual myCharArray?

mac13k
  • 2,423
  • 23
  • 34
Henrik
  • 167
  • 1
  • 1
  • 7

3 Answers3

14

You need to understand that a pointer is only a variable, which is stored on the stack. It points to an area of memory, in this case, allocated on the heap. Your code correctly frees the memory on the heap. When you return from your function, the pointer variable, like any other variable (e.g. an int), is freed.

void myFunction()
{
    char *myPointer;     // <- the function's stack frame is set up with space for...
    int myOtherVariable; // <- ... these two variables

    myPointer = malloc(123); // <- some memory is allocated on the heap and your pointer points to it

    free(myPointer); // <- the memory on the heap is deallocated

} // <- the two local variables myPointer and myOtherVariable are freed as the function returns.
Tim
  • 2,563
  • 1
  • 23
  • 31
Joe
  • 46,419
  • 33
  • 155
  • 245
  • 1
    Thanks for this good explanation detailing the difference of freeing memory from head and stack. For me, the coloring of the source code would be better, thus easier to read, if the <- got replaced by //. – Daniel S. May 03 '13 at 10:35
9

That will be fine and free the memory as you expect.

I would consider writing the function this way:

 void reset(char** myPointer) {
     if (myPointer) {
         free(*myPointer);
         *myPointer = NULL;
     }
 }

so that the pointer is set to NULL after being freed. Reusing previously freed pointers is a common source of errors.

mac13k
  • 2,423
  • 23
  • 34
Jeff Foster
  • 43,770
  • 11
  • 86
  • 103
  • Acually I am doing a review of some code, so my example was a simplified version. In the actual code there is another line of code: myCharArrayp = NULL; which I knew would not work. But then I start wondering if the free would not work either. I guess it all has to be rewritten the way you suggest. Thanks :o) – Henrik Mar 18 '11 at 10:03
  • Joe's answer explains it well. The pointer is a variable stored on the stack and the function gets a copy. That's why you need a pointer to a pointer in the example above. – Jeff Foster Mar 18 '11 at 10:04
  • 2
    Yes you would need a `char **` (or `void **`) but why not just assign `NULL` to the pointer after calling `free` in the code? To quote: " If ptr is a NULL pointer, no operation is performed." so I would say this function is a bit wasteful! – Joe Mar 18 '11 at 10:25
  • 1
    If I called reset(NULL) without the if check, I'd try to dereference a null pointer. The idea of assigning NULL to it afterwards is so that the callee sees the NULL value. That way attempts to reuse the pointer fail in a more predictable value than if it just used the previously freed address. This is definitely a bit wasteful, but I'm trying to suggest trading a bit for more safety instead. Can always be taken out in production. – Jeff Foster Mar 18 '11 at 11:36
  • Yes, you're right on the null dereference, I didn't read it properly. – Joe Mar 18 '11 at 11:50
1

Yes it will work.

Though a copy of your pointer variable will be sent, but it will still refer to the correct memory location which will indeed be released when calling free.

Shamim Hafiz - MSFT
  • 21,454
  • 43
  • 116
  • 176