vergessen
vergessen

Reputation: 61

Simple c function, segfaults on free

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

Answers (3)

Void Star
Void Star

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:

  1. You never use the buffer you allocated with malloc for any useful purpose, so you don't need that malloc nor the memset
  2. You lose the pointer returned by malloc so you can never free it. Your process has leaked memory.
  3. You try to 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

Walter
Walter

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

Some programmer dude
Some programmer dude

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

Related Questions