Reputation: 61
I know this has been asked quite a bit, but every example I looked at never seemed to fit exactly. In the code below if I keep the free()
, the resulting compiled binary segfaults. If I remove it, the code works just fine. My question is, why?
int convertTimeToStr(time_t* seconds, char* str)
{
int rc = 0;
if (str == NULL) {
printf("The passed in char array was null!\n");
rc = 1;
} else {
char* buf = malloc(sizeof(char) * 100);
memset(buf, '\0', sizeof(buf));
buf = asctime(gmtime(seconds));
strcpy(str, buf);
free(buf);
}
return rc;
}
Upvotes: 0
Views: 82
Reputation: 2521
You call malloc
and memset
, which allocates a buffer and sets it to zeroes, but then you overwrite the value of buf
with the return value from asctime
. By the time you call free
, it is on the return value from asctime
, not your original allocation. This has three issues:
malloc
for any useful purpose, so you don't need that malloc
nor the memset
malloc
so you can never free
it. Your process has leaked memory.free
the return value from asctime. The return value from asctime does not need to be freed and should not be freed. This causes undefined behavior, in your case a segfault.Upvotes: 1
Reputation: 45434
You should not be surprised by that, since you've changed the value of the pointer buf
from what malloc()
returned.
char* buf = malloc(sizeof(char) * 100); // value returned by malloc()
memset(buf, '\0', sizeof(buf));
buf = asctime(gmtime(seconds)); // change value of buf
strcpy(str, buf);
free(buf); // buf differs from above
Calling free()
with an argument that was not returned from malloc()
(or calling it for the second time) is undefined behaviour.
Upvotes: 2
Reputation: 409196
The problem is that you reassign the pointer to your allocated memory. What you're doing is basically equivalent to
int a = 5;
int b = 10;
a = b;
and then wondering why a
is no longer equal to 5
.
With the assignment buf = asctime(gmtime(seconds))
you lose the original pointer and have a memory leak.
What the asctime
function returns is a pointer to a static internal buffer, it's not something you should pass to free
.
Upvotes: 3