freeing a pass by copy pointer

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

have more pointer freeing headaches :(
ok say I have this situation:

void ParentFunc(void)
{
   int *ptr = malloc(10);
   int ptr2 = ptr;
   free(ptr2);
   ptr2 = NULL;
   ptr = NULL;
}

will the above free the allocated memory and have no dangling pointer? I think so...

another situation...

void ParentFunc(void)
{
   int *ptr = malloc(10);
   int ptr2 = ptr;
   ChildFunc(ptr2);  //should I use ptr2 or ptr here? 
}

void ChildFunc(int *ptr)
{
   //do stuff, at the end free memory
   free(ptr);
   ptr = NULL;
}

Questions:
Should the parent function have passed by reference (with &) or pass by value was ok? Should it have used ptr2 or ptr?

If pass by reference then, I guess the child function should have been defined as follows?

void ChildFunc(int **ptr)
{
   //do stuff, at the end free memory
   free(*ptr);
   *ptr = NULL;
}

any suggestions?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The compiler will most likely complain about assigning a pointer to an int. Passing an int to a function that expects a pointer will also be cause for the compiler to choke. You're also having an int pointer point to 10 bytes.

Remember that a pointer holds an address. If malloc gives you an address and you pass that address to free, then all is well.you can copy that address any which way to any number of variables as long as you call free with the address that malloc gave you.

When you pass a pointer, it gets passed by value ie the address is the value. But since it is n address, you're passing a reference ie you're saying, "get the value from this address".

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sorry that was my mistake, i meant to type int *ptr2. and yes the malloc should have had sizeof(int). I just tried to type those lines quickly.

having said what you said, so you mean that if the original malloced pointer is ptr and its copy is ptr2 then i can free either in order to free up the allocated memory, I just need to NULL both to avoid dangling pointer.

In terms of passing by value... in child function...so will freeing the passed by value pointer inside the child function free the original pointer?

the only problem I see with the following

void ChildFunc(int *ptr) 
 { 
    //do stuff, at the end free memory 
    free(ptr); 
    ptr = NULL; 
 }

is the last line ptr = NULL, here the nulling does nothing, as the ptr variable is a copy of the original ptr variable from parent function. But I guess if I sent the ptr variable as pass by reference then nulling it inside ChildFunc() would be ok like in the later code sample...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First off, you should use correct semantics.
You are doing appalling things with assigning incompatible pointers.

void ParentFunc(void)
{
   int *ptr = (int *)malloc(10);
   int *ptr2 = ptr;
   free(ptr2);
   ptr2 = NULL;
   ptr = NULL;
}

Untested. But this should work fine.

// ChildFunc needs to be declared before ParentFunc uses it
void ChildFunc(int *ptr)
{
   //do stuff, at the end free memory
   free(ptr);    // fine.  it is a value      
   ptr = NULL;   // pointless since it is a copy
}

void ParentFunc(void)
{
   int *ptr = (int *)malloc(10); // cast first
   int *ptr2 = ptr;  // should be a pointer
   ChildFunc(ptr2);  // yo can use ptr2 or ptr1
}

It is always a wise move to flag a pointer when it is freed. But the child only gets passed a value.

If you want a child to assign NULL, you need to pass the address of the pointer and subsequent indirections. But all this only obfuscates your code. Not only that, but maloc() and free() are seldom appropriate for embedded systems.

If you do use malloc(), you must always check the return value.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks David... see above I acknowledged some of those mistakes you pointed out, and thank you :)

This nulling of the pointer inside the ChildFunc....my child function is actually a RemoveItem function that removes items from linked list. When it removes it if it was the last item it NULLs it anyways and if it wasnt the last item any PREV and NEXT items are rearranged accordingly. So basically the removed item is no longer accessible and at the end is freed using free(*item). In this case I dont see the need to do another *item = NULL. Since the item was already removed from the linked list using the rearrangements and is no longer accessible by any other functions.

If nulling therefore is no longer needed I can then change my function arguements to *item instead of **item I guess...?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Be realistic about your linked list. How many items? How much SRAM do you have?

Each malloc()ed item has a housekeeping overhead. Quite honestly, small lists are easier / safer to do with static arrays.

I suggest that you test your linked lists on a PC where you can debug conveniently.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Untested. But this should work fine.
Well, maybe, it depends on what you expect from the malloc.

int *ptr = (int *)malloc(10);

This will return a pointer to 5 integers (at least on the AVR). If what you really wanted was a pointer to 10 integers, then you would need:

int *ptr = (int *)malloc(10 * sizeof(int));

Regards,
Steve A.

The Board helps those that help themselves.