I wonder, if I have the following code:
var = (double *)calloc(vars_ptr->amount, sizeof(double));
if (var == NULL) {
printf("ERROR: Problem in memory allocation");
exit(1);
}
Is it possible there will be a memory leak? I mean exiting without freeing, since it indicates the memory allocation process didn't take place.
If no memory was allocated, you don't have to free anything.
That said, free(NULL) isn't harmful. It just doesn't do anything.
That said, there is no point in freeing memory just before you're exiting anyway. That's not a memory leak; a leak would be not freeing memory and keeping running.
No, this
var = (double*)calloc(vars_ptr->amount, sizeof(double));
if (var == NULL){
printf("ERROR: Problem in memory allocation");
/* #TODO proper error handling i.e use error no & stderr */
exit(1);
}
doesn't causes memory leak, as if call to calloc() fails i.e memory allocation was failed i.e you don't have to call free().
From C standard
7.20.3.2 The free function
#include <stdlib.h>
void free(void *ptr);
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.
When you call malloc or calloc, and the call returns NULL, that means that nothing has been allocated, so nothing has to be freed, and there's no memory leak.
The case you have to worry about concerns realloc:
newp = realloc(oldp, newsize);
If realloc returns NULL, then oldp still points to the old memory (if any). If you were to write
p = realloc(p, newsize);
this would be a memory leak waiting to happen, the first time realloc failed. (That is, p would contain NULL, and the old, still-valid pointer would be lost.)
If the returned pointer is equal to NULL then this means that the memory was not allocated.
From the description of the function calloc (C11 Standard)
3 The calloc function returns either a null pointer or a pointer to
the allocated space.
You may call free for a null-pointer though this does not have an effect.
On the other hand, you may require a memory of zero size. In this case if the returned pointer is not equal to NULL you have to call free to free the allocated memory.
Here is a demonstrative program
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *p = calloc( 0, sizeof( int ) );
if ( p != NULL )
{
printf( "p = %p\n", ( void * )p );
}
free( p );
return 0;
}
Using an inline compiler its output
p = 0x55efd9c81260
That is though the required size of memory is equal to 0 nevertheless the system allocated memory that needs to be freed.
Your question is a little confusing:
If you are asking whether you should call free(var) before exiting the program, it is obviously not necessary since var == NULL when this memory allocation failed. There is nothing to free in var. Calling free(var) is allowed, but will do nothing.
If you are asking whether you should free other memory blocks allocated by your program before exiting it on a fatal error for this particular allocation attempt, it is not necessary either because all memory allocated by the OS to the program is released upon exit.
Other system resources such as open files, locks, semaphores... should be released automatically as well but you might still leave the environment in an inconsistent state by exiting the program abruptly like that. For example you might leave some files with inconsistent contents, undeleted temporary files, pending network transactions, inconsistent database updates...
the code you uploaded allocates memory, not freeing it.
according to the info at http://www.cplusplus.com/reference/cstdlib/calloc/ and
https://www.tutorialspoint.com/c_standard_library/c_function_calloc) - calloc returns NULL if the function failed to allocate memory from the OS. thus, it's a good practice to check the pointer after the function call, in order to avoi.
I'd say that if the function fails, either you're trying to allocate way too much memory, or that a memory leak already has occured, so I wouldn't worry about exiting the code after failure - it's probably for the best.
Related
when declaring for example a malloc and then checking if it is NULL to see if it has been properly allocated, should I free the memory if it is null, example:
int *p;
p = (int *)malloc(sizeof(int));
if (p == NULL)
{
free(p); //Should I free here or will it create an error?
return NULL;
}
If malloc returns a null pointer it has failed to allocate anything at all, and there's nothing to free.
With that said, passing a null pointer to free does nothing, so it's safe.
On a related note, in C you shouldn't really cast the result of malloc.
Should I free memory in C if it is not allocated properly?
You shouldn't, because you can't, because it turns out the question doesn't even make sense.
malloc either gives you a pointer to properly-allocated memory, or it doesn't.
Those two cases are distinct: It either gives you a non-null pointer, or a null pointer.
A null pointer return means that malloc failed, and did not allocate any memory for you.
Suppose that in the process of trying but failing to allocate the memory that you asked for, malloc did partially allocate some memory, or something. Suppose it was your job to free this. How would you do this? You have no way of referring to that memory! When malloc fails, it returns you a null pointer, and a null pointer points, by definition, nowhere.
It doesn't make much sense to pass a null pointer to the free function. Once upon a time, this was an error, and tended to crash. Today, it's harmless: free checks to see if you've handed it a null pointer, and if so, it quietly does nothing.
So in fact, if malloc partially allocates memory or something, then fails, it has to be malloc's job to clean that up automatically, before returning the null pointer to you.
I have a question, about C-function free().
What will happen, if first I'll allocate memory for char-string, then past '\0' to any position of the string and set the new pointer to the next after '\0' position?
If after I will try use free on the initial pointer, is there a memory leak? Or compilator knows termination position and free all of the allocated memory?
Manuals say "Frees the pointer, allocated by malloc", but I still have no full understanding of this process.
There's an example:
#include "stdlib.h"
int main()
{
int i = 0;
char* test = (char*)malloc(sizeof(char) * 100);
char s = 'a';
for (int i = 0; i < 10; i++)
test[i] = s;
test[10] = '\0';
char* v = (test + 6);
test[4] = 0;
free(test);
return 0;
}
Valgrind says:
Address 0x522d048 is 8 bytes inside a block of size 100 free'd
malloc reserves memory for your use and returns a pointer to that memory. Internally, malloc remembers information about that memory. In particular, it remembers how much it reserved.
When that same pointer is passed to free, free terminates the reservation.
Once that reservation is ended, you should not use any of that memory. In your example, when you call free(test), all of the memory that was reserved by malloc(sizeof(char) * 100) is released. The fact that you put a null character in part of it and have data later after is irrelevant. The fact that you still have a pointer v that points to somewhere in the memory is irrelevant. free releases all of the memory that was allocated, regardless of contents.
(This does not mean that attempting to use the memory will not work. After you call free, the memory is no longer reserved for you to use. But it is possible that nothing will act to prevent you from using it—no trap is guaranteed to occur if you try. But it is also possible that a trap might occur or that other software in your program might use that memory, so your use of it could interfere.)
Memory allocation with malloc allocates the number of bytes requested and returns a pointer to the beginning of the allocated range.
Function free() deallocates the range only when you pass the pointer returned by malloc. Any other pointer passed to free invokes "undefined behavior".
Neither function knows or cares what information you place in the range of allocated bytes.
Moreover, freeing a NULL pointer does nothing since according to the standard value of NULL is internally checked.
I'm starting to learn C programming and stumbled upon a situation that shows my lack of understanding of how memory allocation with malloc() works.
In a loop like the following:
// will only know `xlen` at runtime so I guess I have to use malloc here
char *x = malloc((xlen + 1) * sizeof(*x));
assert(x != NULL); // memory allocation failed
while (fgets(line, sizeof(line), fp) != NULL) {
strncpy(x, line, xlen); // copy first xlen characters of line
x[xlen] = '\0'; // ensure null terminating string
// do something with x
// x can now be "reused" for another line/loop iteration
// free(x) - errors out with "pointer being freed was not allocated"
}
fclose(fp)
free(x);
If the statement free(x) is called inside the loop then when I run this program I get an error message something like a.out(37575,0x7fff964ce3c0) malloc: *** error for object 0x7fab47c02630: pointer being freed was not allocated.
Why am I seeing this error message and what is causing it?
Will the memory address block of x be "re-used" at each iteration of the loop? (I'd say yes, and that would actually be what I wanted in this case) In this case, is it safe to only free the allocated memory of x outside the scope of the loop?
free(x); frees the memory allocated by char *x = malloc(.... It frees all of the memory, and you don't have to worry about how much memory that was, as it keeps track of that. You just have to call free(x); once as you correctly do. This is why you get the error if you free it inside the loop.
Does it mean that the memory address block of x will be "re-used" at
each iteration? (I'd say yes, and that would actually be what I wanted
in this case)
Yes, you use the same memory. It overwrites the memory every time.
In this case, is it safe to only free the allocated memory of x
outside the loop scope?
Yes, you have to free it outside of the loop. Because if you free it, then all of it is freed. If you did that inside the loop, then it would be undefined behavior to keep accessing that memory in following loop iterations.
The malloc() function provides a pointer to an area of memory that can then be used just like any pointer to a memory location.
The way to think of malloc() and free() is to consider it in terms of who owns a memory area. The malloc() function owns the memory that it is managing. When you call the malloc() function, or calloc() function, the function takes some of the memory it is managing and transfers ownership to you. When the function is called and the memory allocated there is a transfer of ownership from the memory management system of malloc() to you and at that point you own that memory and it is up to you to manage it. When the free() function is called to release the memory, you are transferring ownership of the memory area from you back to the memory management system of malloc().
Whenever a transfer of ownership is done, the entity that is giving up ownership is not supposed to do anything further with the memory area since it no longer owns it.
So when you do the malloc() you now own the memory and can use and reuse the memory area as much or as little as you want until such time that you call the free() function to give it back to malloc().
A pointer to a memory region given by malloc() is like any other pointer so far as using it is concerned.
Once you have transferred ownership of a memory area back to malloc() by using thee free() function, you can't call free() again with the same pointer without introducing an error. Once a memory area has been returned using free() you no longer have ownership of the memory so you shouldn't try to do anything else with it and that includes calling free() with the pointer again.
How malloc() manages memory is an implementation detail that will vary depending on the compiler and the C Runtime used. In some cases if you malloc() memory then free() the memory and then malloc() the same amount of memory again you may get lucky and get the same memory area again however it is not something you can count on or should expect.
malloc() provides you a pointer to a memory area that has a couple of guarantees. First of all the memory area provided will be at least as large as you requested. It may be larger but it won't be smaller than what you requested. Secondly the address provided will be on a memory boundary suitable for the machine architecture so that you can use the address provided for any variable type whether a built in such as int or double or a struct or an array of some type.
As the owner of the memory area provided by malloc() you are responsible for giving the memory area back to the malloc() functionality once you are done with it.
Your other primary responsibility is to respect the size of the memory area and to not write a larger data block into the area than the size requested when the malloc() was done. You are guaranteed only the amount of memory requested and writing a larger block of data into the memory will probably overwrite memory that you do not own but is owned by something else.
Unfortunately because the malloc() functionality, at least the optimized or non-debug version of the library, is designed with little as possible overhead, the functionality has few consistency and sanity checks in place. The malloc() functionality trusts that you will obey the rules and guidelines and only use what you own. And often when you break the rules and guidelines, you won't see the effect at the point where you have made a mistake but rather at some other point when some mysterious memory corruption is discovered and your program crashes.
You can use and reuse dynamically allocated memory as long as you have not called free() on it. If you free it and attempt to use it again, then you will have undefined behaviour.
You can continue to reusing memory (eg buf created by char *buf = calloc(sizeOfBuf); ) allocated to you on a single call to calloc(), until free(buf) is called, just as if buf was created statically, eg char buf[sizeOfBuf]; = 0. However, if the size of the buffer initially created by using calloc() needs to change, realloc() is available to do this, and is the preferable method. There are some caveats about using realloc however. Here is an example of using realloc, this one packaged into a function that resizes an existing dynamically allocated buffer, and takes care of some of the caveats:
realloc usage example:
// initial call to calloc
char *buf = calloc(sizeOfBuf);
if(buf)
{
while(someConditionIsTrue)
{
// read new content
//...
//new content needs to be added to buf
char *tmp = realloc(buf, newSizeOfBuffer);
if(!tmp)//if failed...
{
free(buf);//... free original buf to prevent memory loss
return NULL;// return null, caller must test for this
}
buf = tmp;//...else copy new mem location back to original pointer
//continue doing stuff with buf
}
//when done with buf, free it
free(buf);
}
One other suggestion, consider calloc() returns uninitialized memory, i.e. you own a space that contains whatever was occupying it when it was given to you. It is a good idea to follow that command with a method to clean up the buffer:
memset(buf, 0, sizeOfBuf);
Or use calloc().
gcc (GCC) 4.7.0
c89
Hello,
I am wondering if I am thinking correctly here. When I allocate memory using malloc. malloc will return a pointer to a size in memory.
So before I allocate my memory all pointers will have the value NULL.
Using this code snippet:
struct address *db_row = NULL;
db_row = malloc(sizeof(struct address));
db_row->name = malloc(sizeof(char) * 10);
db_row->email = malloc(sizeof(char) *10);
free(db_row->name);
free(db_row->email);
free(db_row);
I have done this in the gdb debugger for db_row before allocating memory:
(gdb) p db_row
$20 = (struct address *) 0x0
(gdb) p *db_row
Cannot access memory at address 0x0
Which is correct, as no memory address has been allocated.
After I allocate memory I get the following when I do the same:
(gdb) p db_row
$25 = (struct address *) 0x602310
(gdb) p *db_row
$26 = {id = 0, set = 0, name = 0x0, email = 0x0}
However, after I have free the memory I still get the same memory address, should it not be NULL as in the first case before allocating any memory?
After freeing the memory:
(gdb) p db_row
$28 = (struct address *) 0x602310
(gdb) p *db_row
$27 = {id = 6300480, set = 0, name = 0x602330 "", email = 0x602350 " #`"}
As you can see its still pointing to the same memory location, is this correct?
Finally, I added this at the end to see if I could do a double free:
if(db_row != NULL) {
free(db_row);
}
if(db_row != NULL) {
free(db_row);
}
I get a stack dump on the second call to free. But as a safety measure should you always check to make sure you are not trying to do a double free?
It it worth setting the pointers to NULL after free them?
db_row = NULL;
Many thanks for any suggestions,
But as a safety measure should you always check to make sure you are not trying to free a NULL pointer?
Calling free() with a NULL pointer is safe and nothing occurs. Calling free() does not NULL the pointer, you may do this explicitly. NULLing a pointer after calling free() would prevent the double free on the same pointer variable:
/* Assuming 'db_row' is referring to a valid address
at this stage the following code will not result
in a double free.*/
free(db_row);
db_row = NULL;
free(db_row);
If another pointer variable is pointing to the same address and is passed to free() then a double free still occurs.
Just because a pointer is not-NULL does not guarantee that it points to a valid address. It is the programmer's responsibility to ensure double free()s do not occur. NULLing pointer variables after a call to free() helps but does not provide a guarantee as multiple pointer variables can be pointing at the same address.
But as a safety measure should you always check to make sure you are not trying to do a double free?
There is no way to query a pointer variable to determine if the memory at the address that it holds has already been free()d. A pointer variable holds an address, nothing more.
It is good practice to set a pointer to null after freeing it unless you are at the end of the scope of the variable; and yes it is normal that free does not do that.
If the pointer is null, calling free on it is safe, and any access to it will generate a core dump, which is much easier to debug than memory corruption or double free that could occur if you use a freed pointer not set to null.
After I have free the memory I still get the same memory address, should it not be NULL as in the first case before allocating any memory?
Because free() only releases the memory that was allocated to you. It dos not set the pointer to NULL.
But as a safety measure should you always check to make sure you are not trying to free a NULL pointer?
If pointer passed to free() is a null pointer, then no action occurs(C99 section 7.20.3.2).
It it worth setting the pointers to NULL after free them?
There is absolutely no merit in doing so, more often it would end up hiding your problems which will raise their ugly head in some or other form.
It is a defensive and dubious style of programming to avoid dangling pointers or double free problems, wherein you try to safeguard yourself against free() getting called on the same pointer.In reality more often or not the double free problem occurs when you different pointers to the same memory and these different pointers are passed to free().
The practice of making the pointer NULL does nothing in the second and more common bug scenario. All of these situations can only be avoided by writing programs by putting in some good thought and periodic code reviews.
To try to be clear here, I'm going to quote from the man page of malloc:
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.
So, to recap:
Free takes a pointer returned by a memory allocation function (NULL or valid)
If it's NULL, nothing happens
If it's a valid pointer it frees the memory
You'll note here it says nothing about changing the address that ptr is pointing to. That's on you to do. So it's very safe to do:
int *p = malloc(sizeof(int));
*p = 5;
printf("p=%d\n",*p);
free(p);
p = NULL;
Now you can call free() all day long on your pointer p and you're OK. If you're concerned about having errors with double free() calls, on recent versions of Linux libc (later than 5.4.23) and GNU libc (2.x) there is a saftely mechanism in place called MALLOC_CHECK_
Instead of getting a stack crash you'll see a message such as:
*** glibc detected *** ./a.out: free(): invalid pointer: 0x0804b008 ***
You can use it in the following ways:
export MALLOC_CHECK_=0 to turn off malloc check and (possibly) let your program crash
export MALLOC_CHECK_=1 you'll get the above warning message
export MALLOC_CHECK_=2 Will call abort(1) and give you a back trace of your code
export MALLOC_CHECK_=3 is just option 1|2 together
What happens if you try to free a memory which is not allocated using malloc/calloc?
Here is what I mean :
void main()
{
int temp = 0;
int *ptr = &temp;
free(ptr);
}
I thought free() would return some error code but free() does not have a return value.
If you call free() on the pointer which wasn't allocated before, it will trigger undefined behavior.
From Linux 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. If ptr is NULL, no operation is performed.
To add to Malcolm's answer: This is undefined behavior by ISO/IEC 9899:1999, 7.20.3.2:
Otherwise, if the argument does not match a pointer earlier returned by the
calloc, malloc, or realloc function [...] the behavior is undefined.
See the draft standard here: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf.
I extended the above code a bit:
#include <stdio.h>
#include <stdlib.h>
void main()
{
int temp = 0;
int *ptr = &temp;
printf("Before: %0X\n", ptr);
free(ptr);
printf("After: %0X\n", ptr);
getchar();
}
If this code is compiled by Visual Studio 2010, in Debug configuration, calling free initiates a "Debug Assertion failed" message. This error message comes from dbgheap.c:
/*
* If this ASSERT fails, a bad pointer has been passed in. It may be
* totally bogus, or it may have been allocated from another heap.
* The pointer MUST come from the 'local' heap.
*/
_ASSERTE(_CrtIsValidHeapPointer(pUserData));
Compiling with MinGW-GCC, the resulting exe runs without error (the "After: ..." line shows the same value for ptr as the "Before: ..." line).
All hell will break loose.
Which means:
If you are lucky, your program will error out and terminate.
If you are not lucky, some attacker will execute arbitrary code using your program (free() will usually try to insert your newly freed "chunk" of memory into some data structure, which usually involves some writes at locations determined by values at/near the pointer you passed).
Anything between these two extremes. Not terminating in error should be considered worse than terminating in error.
In addition to the answers by Malcom and undur_gongor, C on Windows with Visual Studio is the same. The pertinent section from MSDN's description is found here:
The free function deallocates a memory block (memblock) that was previously allocated by a call to calloc, malloc, or realloc. The number of freed bytes is equivalent to the number of bytes requested when the block was allocated (or reallocated, in the case of realloc). If memblock is NULL, the pointer is ignored and free immediately returns. Attempting to free an invalid pointer (a pointer to a memory block that was not allocated by calloc, malloc, or realloc) may affect subsequent allocation requests and cause errors.