Do I need to/can I free a void pointer in C? - c

I have a void pointer as a parameter for a function. It is currently pointing to an int. When I try to free it, it returns a bus error. Should I be freeing void pointers? If so, how do I do so?

You have to answer two questions first:
Was it previously allocated with a malloc family function (e.g. calloc)?
Did you inherit ownership of it when making the function call?
If the answer to both of those is "Yes", then it's at your discretion, though presumably you'd do it at the appropriate time and place to avoid "use after free" type bugs.
When you inherit ownership of a pointer you inherit the responsibility for calling free() when you're done using it, or passing on ownership to another part of your code. If you fail in this responsibility you have memory leaks.
As a general rule you should never free() a pointer unless you know with certainty that's what you're supposed to do, and you're allowed to do it.
Some functions return pointers to things that you do not own, and even if you did, they're not valid for free() because they may be offset somehow. Only the original pointer returned from the malloc-type function can be used with free().
For example:
void* getBuffer(size_t size) {
globalBufferOffset += size;
return &globalBuffer[globalBufferOffset];
}
This returns a pointer in the middle of some structure that may or may not be dynamically allocated. You don't own it. You should not call free() on it.
Read the documentation very carefully to understand your responsibilities. You may need to call a special free-type function when you're done with the pointer. You may not. You may need to pay attention to thread safety. There's a lot of things that can be going on here you need to be aware of before making a decision.

If the pointer is allocated by malloc or something like that, you have to free.
Because, the malloc function returns the void * pointer, so YES, you can/need to free this pointer.
There are some cases you should not free, for example, the code below:
#include <stdio.h>
#include <stdlib.h>
int main()
{
void *p1, *p2, *p3;
int x, y;
p1 = &x;
p2 = malloc(sizeof(int));
p3 = malloc(10);
*(int*)p2 = y;
p3 = "abc";
free(p1); // it raises the fault because p1 is not allocated by malloc
free(p2); // it's OK
free(p3); // it raises also the fault because p3 points to string literal
return 0;
}

You need a corresponding delete each new or a free for each malloc.
If you never wrote a new or a malloc you don't need a free.
Some libraries have their own version of new and free. They would also have corresponding methods and hopefully some documentation. Like SDL_CreateRGBSurface and SDL_FreeSurface.

Related

Freeing a pointer inside a function, and using it in main

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
char* test() {
char* s = "Hello World";
size_t len = strlen(s);
char* t = malloc(sizeof(char)*(len+1));
strcpy(t, s);
free(t);
return t;
};
int main(void) {
printf("%s\n", test());
return 0;
};
I would like to allocate and de-allocate memory inside the function. I tested this code and works, but I am wondering:
Why does this work?
Is it good practice to use the value of a freed pointer in main ?
Once you call free on a pointer, the memory it pointed to is no longer valid. Attempting to use a pointer to freed memory triggers undefined behavior. In this particular case it happened to work, but there's no guarantee of that.
If the function returns allocated memory, it is the responsibility of the caller to free it:
char* test() {
char* s = "Hello World";
size_t len = strlen(s);
char* t = malloc(sizeof(char)*(len+1));
strcpy(t, s);
return t;
};
int main(void) {
char *t = test();
printf("%s\n", t);
free(t);
return 0;
};
malloc reserves memory for use.
free releases that reservation. In general, it does not make the memory go away, it does not change the contents of that memory, and it does not alter the value of the pointer that held the address.
After free(t), the bytes of t still contain the same bit settings they did before the free. Then return t; returns those bits to the caller.
When main passes those bits to printf, printf uses them as the address to get the characters for %s. Since nothing has changed them, they are printed.
That is why you got the behavior you did with this program. However, none of it is guaranteed. Once free was called with t, the memory reservation was gone. Something else in your program could have used that memory. For example, printf might have allocated a buffer for its own internal use, and that could have used the same memory.
For the most part, malloc and free are just methods of coordinating use of memory, so that different parts of your program do not try to use the same memory at the same time for different purposes. When you only have one part of your program using allocated memory, there are no other parts of your program to interfere with that. So the lack of coordination did not cause your program to fail. If you had multiple routines in your program using allocated memory, then attempting to use memory after it has been released is more likely to encounter problems.
Additionally, once the memory has been freed, the compiler may treat a pointer to it as if it has no fixed value. The return t; statement is not required to return any particular value.
It doesn't matter where do you free() a pointer. Once it is free()d, the pointer is not deferrenciable anymore (neither inside nor ouside the function where it was free()d)
The purpose of free() is to return the memory allocated with malloc() so the semantics are that, once you have freed a chunk of memory, it is not anymore usable.
In C, all parameters are passed by value, so free() cannot change the value expression you passed to it, and this is the reason the pointer is not changed into an invalid pointer value (like NULL) but you are advised that no more uses of the pointer can be done without incurring in Undefined Behaviour.
There could be a solution in the design of free() and it is to pass the pointer variable that holds the pointer by address, and so free() would be able to turn the pointer into a NULL. But this not only takes more work to do, but free() doesn't know how many copies you have made of the value malloc() gave to you... so it is impossible to know how many references you have over there to be nullified. That approach makes it impossible to give free() the responsibility of nullifying the reference to the returned memory.
So, if you think that free doesn't turn the pointer into NULL and for some strange reason you can still use the memory returned, don't do it anymore, because you'll be making mistakes.
You are adviced! :)

Do I need to free structs within structs?

I have the following piece of code. I want to properly free all my memory. As you can see, I have a b_struct within an a_struct. I wonder whether I need to manually free the b_struct within the a_struct, and if so, what is the proper way to do it?
#include <stdlib.h>
#include <stdio.h>
struct b_struct {
int c;
};
struct a_struct {
struct b_struct b;
};
int main(int argc, char **argv)
{
struct a_struct *a;
a = calloc(1, sizeof(*a));
a->b.c = 5;
printf("Value: %d", a->b.c);
free(a);
}
I wonder whether I need to manually free the b_struct within the a_struct
No.
From the malloc(3) man page:
The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc(), or realloc().
When you allocated sizeof(struct a_struct) bytes, that includes all members of that structure, including the struct b_struct member. This struct member is no different than an int or char[] member; it's all just one contiguous block of memory to the allocator.
No. Not only do you not need to, you are not allowed to. The memory used in b is a part of the memory used in a; you need to free the latter as a single unit, and that includes all of the memory for b.
In general, your program should call free exactly once for each call to malloc or calloc. This doesn’t mean the number of lines of code calling free needs to be the same as the number of lines calling allocation functions; it means that each time you run the program, each call to free should be paired with exactly one call to an allocation function, and vice versa, with limited exceptions:
If the allocation fails (and returns NULL), you don’t need to call free on NULL.
You can call free on NULL as many times as you want, although you usually don’t want.
You might call library functions which then allocate or free memory internally. This isn’t really an exception; each of those functions must still be matched with a corresponding free or allocation (respectively), but if you just look at malloc, calloc, and free you might miss something.
When your earliest opportunity to free a chunk of memory is right before the program exits, you don’t need to bother, because the OS reclaims all the memory atthat point anyway. This point in particular has its own caveats, but they are at best tangential to this issue.
If you fail to free memory which was allocated, you have a memory leak. Your program will use more and more memory until the OS can’t give it any more, at which point it will probably crash.
If you free memory which was not allocated by one of the standard allocation functions, or free the same memory twice, it gets even worse: this is immediately undefined behavior (UB) and might do anything*. This is the type of bug you would introduce by trying to free b; the memory in question was not the actual pointer returned by calloc, and even if it were it would have already been freed as part of a.
* People often say UB might do anything a lot, but in practice you can often predict what will happen on a real system; it won’t make your computer explode unless you actually have a USB bomb plugged into the computer in question. However, I would classify invalid frees as one of the less-tame types of UB: the errors it introduces can in practice appear later than the actual bug, cause seemingly unrelated issues, and be unstable between multiple runs of the program (meaning things might look fine when you test but fail when you try to use the program, and be hard to debug). With many other forms of UB this is allowed but not as likely in practice to happen.
In this case, no.
You would only need to manually free the inner struct if it was allocated separately from the outer struct. Example:
struct a_struct
{
struct b_struct *b;
};
int main( void )
{
struct a_struct *a = malloc( sizeof *a );
if ( a ) // *Always* check the result of malloc or calloc
{
a->b = malloc( sizeof *a->b );
if ( a->b )
{
// do stuff with a->b->c
free( a->b ); // free in reverse order that you allocated
}
free( a );
}
return 0;
}
You should only free pointer values returned from malloc, calloc, or realloc.

Return a pointer to a dynamically-allocated struct vs. requiring allocated memory from the calling function?

In C, it is possible for functions to return pointers to memory that that function dynamically-allocated and require the calling code to free it. It's also common to require that the calling code supplies a buffer to a second function, which then sets the contents of that buffer. For example:
struct mystruct {
int a;
char *b;
};
struct mystruct *get_a_struct(int a, char*b)
{
struct mystruct *m = malloc(sizeof(struct mystruct));
m->a = a;
m->b = b;
return m;
}
int init_a_struct(int a, char*b, struct mystruct *s)
{
int success = 0;
if (a < 10) {
success = 1;
s->a = a;
s->b = b;
}
return success;
}
Is one or the other method preferable? I can think of arguments for both: for the get_a_struct method the calling code is simplified because it only needs to free() the returned struct; for the init_a_struct method there is a very low likelihood that the calling code will fail to free() dynamically-allocated memory since the calling code itself probably allocated it.
It depends on the specific situation but in general supplying the allocated buffer seems to be preferable.
As mentioned by Jim, DLLs can cause problems if called function allocates memory. That would be the case if you decide to distribute the code as a Dll and get_a_struct is exported to/is visible by the users of the DLL. Then the users have to figure out, hopefully from documentation, if they should free the memory using free, delete or other OS specific function. Furthermore, even if they use the correct function to free the memory they might be using a different version of the C/C++ runtime. This can lead to bugs that are rather hard to find. Check this Raymond Chen post or search for "memory allocation dll boundaries". The typical solution is export from the DLL your own free function. So you will have the pair: get_a_struct/release_a_struct.
In the other hand, sometimes only the called function knows the amount of memory that needs to be allocated. In this case it makes more sense for the called function to do the allocation. If that is not possible, say because of the DLL boundary issue, a typical albeit ugly solution is to provide a mechanism to find this information. For example in Windows the GetCurrentDirectory function will return the required buffer size if you pass 0 and NULL as its parameters.
I think that providing the already allocated struct as an argument is preferable, because in most cases you wouldn't need to call malloc/calloc in the calling code, and therefore worrying about free'ing it. Example:
int init_struct(struct some_struct *ss, args...)
{
// init ss
}
int main()
{
struct some_struct foo;
init_struct(&foo, some_args...);
// free is not needed
}
The "pass an pointer in is preferred", unless it's absolutely required that every object is a "new object allocated from the heap" for some logistical reason - e.g. it's going to be put into a linked list as a node, and the linked-list handler will eventually destroy the elements by calling free - or some other situation where "all things created from here will go to free later on).
Note that "not calling malloc" is always the preferred solution if possible. Not only does calling malloc take some time, it also means that some place, you will have to call free on the allocated memory, and every allocated object takes several bytes (typically 12-40 bytes) of "overhead" - so allocating space for small objects is definitely wasteful.
I agree with other answers that passing the allocated struct is preferred, but there is one situation where returning a pointer may be preferred.
In case you need to explicitly free some resource at the end (close a file or socket, or free some memory internal to the struct, or join a thread, or something else that would require a destructor in C++), I think it may be better to allocate internally, then returning the pointer.
I think it so because, in C, it means some kind of a contract: if you allocate your own struct, you shouldn't have to do anything to destroy it, and it be automatically cleared at the end of the function. On the other hand, if you received some dynamically allocated pointer, you feel compelled to call something to destroy it at the end, and this destroy_a_struct function is where you will put the other cleanup tasks needed, alongside free.

Freeing a character pointer

I have a function which is called multiple times during the program's execution. In said function, I have a dynamic character pointer which I resize numerous times.
My question is: do I need to free this pointer before the end of the function?
void functionName()
{
char *variable = (char *) malloc(0);
//variable is resized with realloc x number of times
//should free be called here?
return;
}
I should also note that I have tried to free the pointer, however, gdb gives me warnings when I do so.
Yes, you have to free it or you'll leak the memory. Your code should look something like this:
void function(void)
{
char *variable = (char *)malloc(0);
variable = realloc(variable, 10);
// do something with new memory
variable = realloc(variable, 20);
// do something with more new memory
free(variable); // clean up
}
Calling malloc(0) is a little weird, I think.
A few points to make:
I can't see how you use realloc() in your code, but if you're using it like this, it's wrong:
variable = realloc(variable, amount);
When it's unable to allocate more memory, realloc() returns NULL but leaves the original pointer unaltered. In the above line, this means that variable is NULL and we've lost access to the memory it pointed to, but that memory hasn't been freed. The correct idiom is this:
void *tmp = realloc(variable, amount);
if(tmp)
{
// success! variable invalid, tmp has new allocated data
variable = tmp;
}
else
{
// failure! variable valid, but same size as before, handle error
}
The reason you should use the second one is because, with realloc(), failure is bad, but is quite recoverable in many situations, unlike malloc() where failure usually means "stop everything and die."
This is a more contentious issue, but it is questionable whether or not you should cast the return value of malloc() and realloc() like you do. Consider:
// functionally identical in C
char *a = malloc(10);
char *b = (char *)malloc(10);
In C++, the cast must be made, because in C++ void * cannot be implicitly converted to another pointer type. (I think this is a language mistake, but it's not my place to judge.) If your code is C++, you should be using new and delete anyway. If your code is C but needs to compile with C++ compilers (for some inane reason), you have no choice but to cast. If you don't need to compile C code with C++ compilers (which is similar to having to run Ruby code in a Python interpreter), continue to the points below, which are why I think you shouldn't cast.
In C89, if a function is used without being declared, it will be implicitly declared as returning an int. If, say, we forgot to #include <stdlib.h> and we called malloc(), the version without a cast would cause a compiler error (implicit casts from int to char * aren't allowed), while the version with the cast would (wrongly) tell the compiler "I know this sounds crazy, but cast it anyway." Most compilers will give you a warning for implicit (or incompatable) declarations of built-in functions like malloc(), but the cast does make it harder to find.
Say you have some data:
float *array = (float *)malloc(10 * sizeof(float));
Later, you discover that you need more precision on your data, and have to make this a double array. In the above line, you need to change no more than 3 different places:
double *array = (double *)malloc(10 * sizeof(double));
If, on the other hand, you had written:
float *array = malloc(10 * sizeof *array);
You would only need to change float to double in 1 place. Furthermore, always using sizeof *obj instead of sizeof(type) and never using casts means that a later call to realloc() can work without any changes, while using casts and explicit type names would require finding anywhere you called realloc and change the casts and sizeofs. Also, if you forget, and do this:
double *array = (float *)malloc(10 * sizeof(float));
On most platforms, array will now only be an array of 5 elements, assuming the alignment isn't off and the compiler doesn't complain that you're assigning a float * to a double *. Some consider the warning the compiler issues to be helpful, as it points out potentially incorrect lines. However, if we avoid sizeof(type) and avoid casting, we can see that the lines won't be incorrect, so having the compiler draw attention to them is wasting time we could be using to program.
From the man pages:
If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().
So, I believe the answer is "yes" :).
Yes you need to call free() once to release the block of memory. You do not need to call free for the subsequent reallocs() that you are doing, even if those return a different address/pointer. The memory manager knows that the old block is not needed any longer and will free() it.
You should be able to just call free(variable) at the end. If realloc ever has to move the data in order to resize it, it calls free internally, you do not need to worry about that.
Also, where you initialize variable, you could just set it to NULL instead of calling malloc; realloc will work just like malloc the first time.
Have a look at some of the answers I have given to a couple of questions in relation to memory management:
Why are memory leaks common?
What's the point in malloc(0)?
C String confusion?
Need help in solving segmentation fault.
C stdlib realloc issue?
C: Creating array of strings from delimited strings.
All of the above point out the obvious thing, for every malloc there is a free, if not you have a memory leak, so it is imperative that you free the memory when you are finished with your pointer variable that is mallocd.
Hope this helps,
Best regards,
Tom.
int main(int argc, char *argv[])
{
char *p = malloc(sizeof(argv[1]));
p = argv[1];
printf("%s\n", p);
free(p);
return 0;
}
iam getting the glibc error
hello
*** glibc detected *** ./a.out: munmap_chunk(): invalid pointer: 0x00007fff66be94c6 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7f38dca1db96]
./a.out[0x4005ed]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7f38dc9c076d]

Is this use of C pointers safe from leaking memory?

char *a() {
char *t = malloc(8);
t[0] = 'a';
t[1] = 'b';
//...
t[7] = 'h';
return t;
}
int main(void) {
char *x = a();
//do something with x
//...
free(x);
return 0;
}
Does this code have any potential problems since memory is allocated in a() and used memory in main()?
First, a() is declared as returning void, but you attempt to return a char*. Change the signature to return a char*.
Second, your function is fine, but your example code has a memory leak because you never free the memory that the returned pointer points to.
Third, as gbrandt pointed out, you are not checking for success after the call to malloc. malloc can fail, and checking to see if it did is a good habit to get into.
Another way to accomplish this would be to pass a pointer to a pointer into a() instead, and then the caller has to create the pointer themselves before passing it to a(), but either way you still need to free the memory. To be honest, I would go with your approach over this in this case. There is no compelling reason to do it this way, just thought I would mention it.
void a(char **p)
{
*p = malloc(8);
if (*p)
{
**p[0] = 'a';
**p[1] = 'b';
...
**p[7] = 'h';
}
}
int main(void)
{
char *x;
a(&x);
//do something with x
.....
free(x);
}
If this alternate approach confuses you, please let me know as I would be happy to provide an explanation (though, at the moment, I need to get back to work!)
All good advice above. Small problems with the code, the big one is...
You are not checking for success in the malloc or after the function call. Never forget error handling.
No problems—in fact, this is the correct way to allocate memory that will still be used after a function returns—but you may want to free() the memory when you're done using it. Eight bytes wouldn't be a problem, but coding against memory leaks is a good habit to get into.
Apart from having the wrong return type on a() (should be char * instead of void), the code doesn't have any problems.
Just be sure to free() the memory you allocated when you're done with it.
Most of the answers here indicate that this isn't a problem, just remember to free() it later. This is technically true, but is really a problem. Any time you allocate memory in one scope and expect it to be freed in another, you are asking for a memory leak. People don't remember to free the memory. There is also the problem that the caller will have to know that you used malloc and not alloca() or new() or something else. If they call anything but the matched deallocation routine, the results are undefined.
In short, it is usually a mistake to allocate memory and pass it back to the caller.
It is better to expect the memory to be allocated by the caller because if they allocate it, they will remember to free it and to do so correctly.
No you won't have any problems explicitly because you allocated the function in a and use it in main.
As long as you remember to free the memory that x points to then you won't have any problems. By using malloc() you've allocated memory on the heap which is left alone when returning to the calling function.
Thanks. I just edited the code. I guess this time it should have no problem. Btw, in C, when a function finishes, does the compiler clear all variables (including array & pointer) in the stack?

Resources