Should I free char* initialized using string-literals?
String literals are stored in such a way that they're available for the lifetime of the program; if you write
char *ptr = "This is a test";
all that's written to ptr
is the address of the string literal "This is a test"
. Even if the ptr
variable goes out of scope, the string literal continues to exist in its own section of memory, which is not the same section used by malloc
(at least, not at a logical level). Note that multiple instances of the same string literal may resolve to the same location; IOW, given
char *p0 = "This is a test";
char *p1 = "This is a test";
p0
and p1
may both contain the same address (it's up to the compiler whether multiple occurrences of string literals are mapped to the same location or not).
When you call Container_new
, all you're doing is copying an address to container->buffer
and globalBuffer
; both wind up pointing to the same thing that exists independently of either of them. free
-ing container
doesn't affect the string literal that container->buffer
points to, so printf(globalBuffer);
still displays "Test-string."
.
In summary, you should not call
free(container->buffer);
for this particular program, since you didn't assign the result of a malloc
, calloc
, or realloc
call to it.
If, OTOH, you had written Container_new
as
Container* Container_new(char* buffer)
{
Container* container = malloc(sizeof(Container));
container->buffer = malloc(strlen(buffer) + 1); // Allocate memory to
if (container->buffer) // store a *new* instance
{ // of the input string.
strcpy(container->buffer, buffer); // This will need to be
} // freed before freeing
globalBuffer = buffer; // the container
return container;
}
then you would need to free container->buffer
before freeing container
.
You shall never free()
memory that you did not malloc()
ed.
The way the compiler implements string-literals is not your business: it's an implementation detail. You can free()
a pointer to memory that you allocated using malloc()
, and only those, or you are risking the life of your system.
Ideally, malloc()
calls and free()
calls should appear on the same "design level" (inside the same implementation file for the same module for example), and they should match perfectly: one free()
for each malloc()
. but that's not always possible.
(Note that some library allocates blocks of memory, returns pointers to those blocks, and instructs you to free them. in this case, you are allowed to free those pointers, but that is a bad design practice from the people who created the library.)