C pointer and memory leak - c

Im new to C. I have seen that in many examples malloc() always pairs up with free(). But if I do something like this: say, *p = "a string" , can I free the pointer p and will it cause memory leak issue?
EDIT: thanks for all the replies!
so my question becomes: if i have *p = "a string" in a function, does that mean all the memory which is used for this function call will be automatically "freed" by the compiler when the function ends so I don't have to manually manage anything to deal with memory?

No, you can not free it, and neither should you.
When you make a pointer point to e.g. a string literal, it points to memory not allocated by you. You should only free memory you explicitly allocate (with e.g. malloc, calloc or strdup).
Other function may allocate memory that you need to free as well, but then they should state that in their documentation.
As a general rule of thumb: If you explicitly allocate some resource (like memory or files), then you should free it too.

For starters you should write const char *p = "a string"; as it's undefined behaviour to modify the string literal (e.g. using statements like p[0] = 'A';). Dropping the const will get you into trouble.
And you must not try to delete the pointer memory; that's undefined behaviour too.
The golden rule: malloc and free are always paired.
Rest assured that, in your case, the memory occupied by your string literal will be released gracefully back to the operating system by the C runtime on program exit.

When you do *p = "a string", you have a pointer p that points to a string literal. No memory is allocated dynamically in this case. So, no need to free p and neither should you.

No. "a string" is data stored in read-only-static memory and p is a pointer that points to it. You only free pointers to memory which was allocated with malloc.

You don't need to free this pointer as it points to a string constant. It is actually may cause undefined behavior if you will try to free it.
The basic rule of the memory management: if you called malloc() to get a memory, you shoudl use free() to release it when you do not need it.

Related

Dynamic memory allocation and pointers related concept doubts

On the first note: it is a new concept to me!!
I studied pointers and dynamic memory allocations and executed some program recently and was wondering in statement char*p="Computers" the string is stored in some memory location and the base address,
i.e the starting address of the string is stored in p, now I noticed I can perform any desired operations on the string, now my doubt is why do we use a special statement like malloc and calloc when we can just declare a string like this of the desired length.
If my understanding of the concept Is wrong please explain.
Thanks in advance.
In this declaration
char*p="Computers";
the pointer p is initialized by the address of the first character of the string literal "Computers".
String literals have the static storage duration. You may not change a string literal as for example
p[0] = 'c';
Any attempt to change a string literal results in undefined behavior.
The function malloc is used to allocate memory dynamically. For example if you want to create dynamically a character array that will contain the string "Computers" you should write
char *p = malloc( 10 ); // the same as `malloc( 10 * sizeof( char ) )`
strcpy( p, "Computers" );
You may change the created character array. For example
p[0] = 'c';
After the array is not required any more you should free the allocated memory like
free( p );
Otherwise the program can have a memory leak.
A simple answer to that would be by doing
char *p = "Computers";
you are basically declaring a fixed constant string. With that means you cannot edit anything inside the string. Trying to do so may result in Segmentation Fault. Using malloc and calloc would allow us to edit the string.
Simply do this on p[0] = 'c' and you will see the result
A statement like
char *p = "Computers";
is not an example of dynamic memory allocation. The memory for the string literal is set aside when the program starts up and held until the program terminates. You can’t resize that memory, and you’re not supposed to modify it (the behavior on doing so is undefined - it may work as expected, it may crash outright, it may do anything in between).
We use malloc, calloc, and realloc to allocate memory at runtime that needs to be writable, resizable, and doesn’t go away until we explicitly release it.
We have to use pointers to reference dynamically-allocated memory because that’s just how the language is designed, but pointers play a much larger role in C programming than just tracking dynamic memory.
as a novice, I described below as my own thinking…
Dynamic memory completely depends on the pointer. I mean without pointer knowledge you are able to cope up with dynamic memory allocation. (stdlib) library function where store calloc, malloc, relalloc and free.
malloc initialized no bit mentioned, calloc mainly used for the array.
realloc used to increase or decrease size.
To simply say it is not as hard as what you first think. if you declare an array[500] initial declare but you used 100 and the rest of 400 bits remove to use dynamic memory.

Allocating array on heap in C

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.

Where the char* is pointing to?

I have some very basic questions regarding pointers and memory allocation.
In below code where does pointer c actually point to? In other words where does the string "xyz" get stored in memory (stack/heap etc.)?
What will happen to memory location allocated for a as I am not using it anymore?
Code seems to work well if I un-comment the commented section. What's happening with the memory in that scenario?
#include <stdio.h>
main()
{
char *c;
//c = (char *)malloc(2);
c = "a";
c = "xyz" ;
printf("%s",c);
return 0;
}
Output:
xyz
Edit:
After reading few of the answer and first comment another question came up in my mind:
In below case, where do the strings get stored? Can I alter them later on?
char *c[] = {"a","xyz"};
The specific details are implementation dependent, but in most common implementations, literal strings like "a" and "xyz" are stored in the text section of the program, like the machine code that implements the program. Assigning a = "xyz"; sets a to point to that location in memory.
The memory for "a" is unaffected. However, an optimizing compiler may notice that c was never used between that assignment and being reassigned, so it could simply ignore the first assignment, and never allocate any space for "a" at all.
The memory you allocated with malloc() stays allocated until the program ends. Allocating memory without freeing it is called a memory leak, and you should try to avoid it.
1.In below code where does pointer 'c' is actually pointing to?In other words where does the string "xyz" get stored in memory(stack/heap etc.)?
will place xyz the read-only parts of the memory and making c a pointer to that, a variable of type pointer-to-char, called c , which is initialized with the location of the first character in that unnamed, read-only array.you created automatic storage (often called the stack). Here you just point to memory in text section.
2.What will happen to memory location allocated for"a"' as i am not using it anymore?
As per your code you not allocated any memory just you assign string literals to that.If you allocate then need to free it.
3.Code seems to work well if I un-comment the commented section.Whats happening with memory in that scenario?
If you un comment the allocation statement to allocate memory then also it point to you literal string but you need to free that memory.
Now for case
char *c[] = {"a","xyz"};
when you declare and initialize words, it'll be allocated on the stack as any other automatic array and its items will be assigned to pointers to the beginning of each string constant.Also to alter this string may illegal.
"xyz" and "a" are string literals which is mostly available in string table.
"xyz" is printed because it is recently assigned to that pointer.
To a place in the heap/stack in the READ-ONLY part of the memory which the string is in. When assigning a string literal directly into a pointer, the program searches for that string in the memory, if it exists through the short search he's doing, it'll point to it, if it doesn't - it will create it. Either way it's read only so it'll be the same as a const char* so you can't change it (of course you can somehow manipulate it, maybe by another pointer or so).
Nothing, it'll stay unaffected.
What's happening is that malloc returns a pointer and you just ignore it, you go to another address containing a and it will not have the same influence as strcpy(c, "a"); as you ignore the allocated memory and its pointer - you do not free it. Generally, nothing's happen if you don't free the memory (I mean, at the end of the program it is freed automatically by the OS) but it WILL take memory within the program so if i'd allocate, let's say 1000000 bytes (assuming it succeeded), allocating more heap memory would be a problem :P
about the other question... You can't alter them through that pointer, try and it will throw an interrupt in the middle of the program and it'll probably stop responding.

Understanding concept of free

Tried the following code :
#include<stdio.h>
int main()
{
int *p,*q;
p = (int *)malloc(sizeof(int));
*p =10;
q = p;
printf("%u \n",p);
printf("%u \n",q);
free(p);
printf("%u \n",p);
return 0;
}
The output got is as follows :
[root#lnxdesk Tazim]# ./a.out
154804232
154804232
154804232
Why is that address inside p is still printed even if I have done free(p);?
What has free(p) done then?
I want to understand the concept of free/malloc clearly. Any help will be valuable.
free() only frees the memory on the heap. It does not change the value of your pointer. If you tried to print the memory pointed by your pointer, you'll probably get some kind of garbage.
Also, when you called free, you gave it the pointer, not the address to your pointer, so free can't change your pointer...
That's undefined behavior - once you've freed the pointer the address stored becomes invalid and you can't do anything with it - not only you can't dereference it, but you can't even printf() the pointer value.
You are printing the pointers, i.e. the address of the memory zones allocated for you ints. Freeing a memory zone with free does not set the pointer's address to 0x00 as I think you expect.
It just tells the OS that the memory zone is available again for future re-use.
If you were printing *p after free(p), you would have problems.
malloc() and its ilk reserve space in a memory storage area called the "heap" and return a pointer to that reserved area. So in your sample above p is given a pointer to, probably, a four-byte memory region that has been reserved for its use (whose address happens to be 154804232 this time around). When you do *p = 10 you are now placing the integer value 10 into the memory pointed to. When you do q = p you're now making q point to the same chunk of reserved heap memory.
free() and its ilk just unreserve the memory. When you call free() you're saying "I'm not going to use this memory anymore". All free() does is tell the memory management system that the block of memory is now available for use once again. It emphatically does not change your pointer. It just signals that the block of memory is available. After that it is up to you to ensure that you do not use that pointer again.
If you do use that pointer again it may work fine. Once. Or twice. Or a thousand times. It'll work fine, basically, until you use it after someone else claims that memory block you've said is free and does something with it. When that transpires, Bad Things Happen<tm>. Please don't make bad things happen.
Remember : a pointer is nothing but an address. Before, after your malloc, or free, it'll give you the same result. The only thing that malloc() does is reserve space at this address. The only thing that free does is release it (most probably, mark this address as usable to store other things, "cleaning" would be time consuming).
This is why putting your pointer to NULL after a free is a good idea ; because you can be sure if the pointer is connected to something or not.
free does not reassign the pointer to point to something else. In fact, the C standard
does not mention anything be done with the pointer. This is all it says in the description:
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, or realloc function, or if the
space has been deallocated by a call
to free or realloc, the behavior is
undefined

What is the difference between freeing the pointer and assigning it to NULL?

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.

Resources