I have many structures, one of which looks like
typedef int Info;
typedef struct
{
Info info;
} Item;
So if I allocate like so:
ItemRef a;
a= malloc(sizeof(ItemRef));
where ItemRef is just typecasted int.
My question is if I deallocate a now, will info inside it also be deallocated?
Because when I tried assigning vale to info in a and then deallocating is and then printing it I was still able to access the value.
So does that mean deallocating a structure does NOT deallocate its components ? Even though I didn't have to individually allocate the components?
Deallocating a struct does deallocate the space for its members. However the rules of the C language do not require that the freed memory is zeroed out or made inaccessible in any way. All freeing does is tell the memory manager that you've finished with that bit of memory and it can reuse it at its discretion.
So, in a typical implementation, if you still have a pointer to the freed memory the compiler won't do anything to stop you accessing it. Doing so puts you in the realm of undefined behaviour which means anything can happen. Messing up in this way and accessing freed memory is a source of annoying and difficult to find bugs in C programs because the behaviour is often not consistent.
From http://opengroup.org/onlinepubs/007908775/xsh/free.html
The free() function causes the space pointed to by ptr to be
deallocated; that is, made available for further allocation. If ptr is
a null pointer, no action occurs. Otherwise, if the argument does not
match a pointer earlier returned by the calloc(), malloc(), realloc()
or valloc() function, or if the space is deallocated by a call to
free() or realloc(), the behaviour is undefined. Any use of a pointer
that refers to freed space causes undefined behaviour.
As per the documentation, the free doesn't initializes all the memory bits, it freed, to any value. Thus the memory (might) still contain the old value. but its undefined behavior to refer it as stated.
The best practice is to::
free(a) ;
a = NULL ;
Related
I have two pointers, p1 and p2, which both point to a dynamically allocated piece of memory - let's just say it's an array of int with size 16.
p1 = (int *)malloc(sizeof(int) * 16);
p2 = p1;
If I do free(p1), does it keep the dynamically allocated memory in tact since p2 is also referring to it, or does it just deallocate the memory, and the pointers become useless (assuming we enter new data there).
Short answer: it deallocates the memory and the pointers point to a non-allocated memory address.
A bit of context: In C, the dynamic allocation of memory and the fact that the memory is referenced by a pointer are unrelated. You can have a piece of memory allocated but not referenced by any pointer (this is called memory leak and it is bad because you won't be able to deallocate it), and you can have a pointer that points to a memory address which is not allocated.
Another topic is how this works for languages in which you don't allocate and deallocate explicitly the dynamic memory but this task is delegated to a garbage collector: in this case, it may be possible that the garbage collector would not deallocate that memory space because you are referencing it with another pointer, so you may still be wanting to use that data (but it depends on the logic of the garbage collector).
It becomes useless. In the manual of free, it says:
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().
Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. If ptr is NULL, no operation is performed.
You can see that free has got nothing to do with the pointer itself, but with the piece of memory it's pointing to, so if you use free over p1, the other pointer will point to memory that has been freed, which means that it is useless.
If you free p1 then your memory is released and is no longer available to be used. Any copy of p1 is also invalid, even though it still points to the same location, just like p1 itself is not changed, but still invalid to be used.
I'm allocating an array of of "Todo" structs on the heap like so:
struct Todo *todos = malloc(n * sizeof(*todos));
My understanding is that I have now allocated memory for all of my n Todo structs. So if I want to save some values I can just do for example:
todos[i].id = 1;
The problem now is that if I try to free that memory using free(&todos[i]); I get an error telling me that I haven't allocated that pointer.
My question is now, do I just need to free the todos array and not every element on its own?
You have allocated one single block of memory for all your Todo structures. You can not free a single element. Just like you should not free elements of a non-heap allocated array.
Each call to malloc (or calloc) should be matched by a single call to free.
A little bit of background to Some programmer dude's answer
C11 standard, 7.22.3.3 "The free function", paragraph 2:
The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.
[emphasis by me]
Background (second level...) is that typically, you did not only receive the memory starting at the pointer, but additionally there is some kind of (machine/OS specific) control block right before the pointer's address that is needed to free the memory again.
You might try to peek at this control block by reading some bytes right before the pointer (just out of curiosity), but be aware that this actually is undefined behaviour as well (so don't ever do this in production code!) and might lead to your programme crashing.
As a reference, always that you do:
WhateverTypeInTheWorld *var1 = malloc(whateveryouwanttocompletearray);
then, you have to do
free(var1); /* use the same value you received from malloc() */
to return the memory back... as you did only one malloc(), you can do only one free() and pass to it the same pointer you got from malloc().
When you write:
free(&todos[i].i);
you are passing free the i-esim element field i's address, and not the pointer you received from malloc(). Probably you understood that you can free part of the memory you received... but it doesn't work that way... you get the memory in chunks, and you have to return it in those same chunks you received from malloc.
I have a c function that looks like this
void fn(void *data) {
type *p=malloc(sizeof *p);
p=data;
...
free(p);
}
If I understand correctly, the two problems with this are that the malloc sets aside some memory for p, but the pointer in p is then immediately overwritten by the pointer data so nothing is pointing to the memory allocated to p. Also, the subsequent free actually frees the memory at data so that whatever function called fn will no longer be able to safely access it. Is this right?
What I probably meant to do is:
void fn(void *data) {
type *p;
p=data;
...
}
Since there's no malloc there's nothing to free and the pointer in data continues to point to allocated memory?
EDIT: I should point out that I know for sure that the pointer in data is actually a pointer of the same type as p.
FURTHER EDIT: The pointer in data points to something that was malloc'd elsewhere.
Yes. You understood right. Assigning data to p after allocating memory to p will leave no pointer to the allocated memory by malloc.
A block of memory that's no longer accessible to a program is said to be garbage. A program that leaves garbage behind has a memory leak.
Unfortunately, unlike some other languages, C doesn't have garbage collector.
Another thing is that calling free(p) will invoke undefined behavior because the argument to free must be a pointer that was previously returned by a memory allocation function (or it could be a NULL pointer).
Yes, the function should not free the memory it did not allocate. The principle worth following in most cases is: do not allocate and deallocate in different contexts.
So I'm new to C and creating some simple programs to help me get a hang of things.
Let's say I have a struct as follows:
typedef struct {
char* field;
} something;
And I dynamically allocate space for 10 of these as follows:
something* stuff = calloc(10, sizeof(something));
Let's say I then want to delete one of these somethings. Would it make sense to do:
free(&stuff[4]);
Or would that only make sense if I had made all of these pointers to somethings instead of a contiguous block of somethings?
If I did that and it worked, would:
stuff[4] = malloc(sizeof(something))
Then be all I need to re-add a "something" to that index?
Or, in general, do we usually deal with such structures as a block of memory that contains pointers to the structs, not the structs themselves?
Thanks.
The rule is very simple. You can and should free precisely that which you allocated. That is, you must only pass pointers to free() which you received as the return value of malloc/calloc/realloc etc.*, or a null pointer. Nothing else may be passed to free().
So, you can free tne entire array, or nothing at all.
(Note also that "freeing a single element from the middle" would be utterly pointless, because you would have no way of iterating over such a "holy" array sensibly.) If you want to deallocate some memory, allocate a new range, copy the desired elements over and free the original array.
*) Some quasi-standard functions may indirectly return dynamically allocated memory which you must fre; check the documentation. Some examples are strdup, GNU's scanf, and GCC's abi::__cxa_demangle.)
According to the man pages
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(). Otherwise, or if free(ptr) has already been called before, undefined behavior occurs.
You can only free the whole block of data. So do not attempt to free anything else.
Could somebody tell me the difference between:
int *p;
p=(int*)malloc(10*sizeof(int));
free(p);
or
int *p;
p=(int*)malloc(10*sizeof(int));
p=NULL;
free will deallocate the memory that p points to - simply assigning it to NULL will not (and thus you will have a memory leak).
It is worth mentioning that it is good practice to assign your pointer to NULL AFTER the call to free, as this will prevent you from accidentally trying to access the freed memory (which is still possible, but absolutely should not be done).
There is no garbage collection in C, so if you don't explicitly free a chunk of memory, it will never get freed, even if there are no references to it. Maybe you come from a background in garbage collected languages, so it might be hard to change your way of thought, but it's always important to remember to "manually" free all resources in low-level languages like C.
Hope this helps
Cheers
p is pointer (to a block allocated dynamically in memory ["on the Heap"])
This means that p is a variable which contains the address in memory of a particular block (or some particular size, in the example a block big enough to hold 10 integers).
free(p); instructs the memory management logic (of the C Runtime) that the memory previously occupied by the block which p points to can be reused.
p = NULL; sets the value of p to NULL (the address it formerly contained is lost) but the block in memory it pointed too is still considered in use.
There can be some confusion because in languages such as Java, C#, Python etc. merely assigning the variable to NULL (or to another address for that matter), will automatically free the underlying memory (assuming no other references to this address exist in other live variables).
This is not the case in C or C++, leading to errors like the following:
free(p);
// possibly some some code etc.
// later:
p[6] = 'a'; // <<--- Ouch we're modifying whatever new variable is there !!!
or
// didn't call free(p)
p = NULL;
// now the memory allocated for p is held in memory even though it
// is not going to be used (assuming no copies of p or of pointers to part
// of that block were made.
The latter case is only wasteful of resources, the former can lead to hard to find bugs.
That's why a typical C idiom is:
free(p);
p = NULL;
Not calling free and directly assigning to NULL will lead to a memory leak as explained by others. You can refer to this link to get clear details about memory leaks and other memory related problems.
The better way is to first free the memory and then set it to NULL:
free(p);
p = NULL;
Freeing the allocated memory deallocates it and allows that memory to be used elsewhere while the pointer to where the memory was allocated is preserved.
Setting a pointer to the allocated memory to NULL does not deallocate it.
If you are using an implementation that uses a heap-based malloc, debug something that allocates, uses and frees memory, and do the same to something that allocates, uses, and sets the pointer to the memory to NULL.
Memory management is implementation-dependent (see http://en.wikipedia.org/wiki/Malloc#Implementations).
1.
int *p;
p= (int * ) malloc(10*sizeof(int));
free(p);
the memory is released back to the heap. but the pointer still pointing to the freed memory location. Thus if its further used , would lead to a memory corruption.
thus correct thing to do is resetting the pointer to NULL explicitly to avoid further usage of that pointer .
its not advisable to type cast the return pointer in C
2.
int *p;
p=(int * )malloc(10*sizeof(int));
p=NULL;
This would result in a memory leak : as the allocated memory is not freed here. you are just reset the pointer to NULL.
p=NULL does not deallocate the memory. If you don't need to use the memory pointed by p anymore you should use free() otherwise there will be memory leak. You should also set p=NULL after calling free() to avoid erroneously accessing that memory again in the future.