简单的c功能,免费的段错误

时间:2017-06-16 16:34:54

标签: c

我知道这已经被问了很多,但我看过的每一个例子似乎都不合适。在下面的代码中,如果我保留free(),则生成编译的二进制段错误。如果我删除它,代码工作正常。我的问题是,为什么?

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;
}

3 个答案:

答案 0 :(得分:3)

问题是您重新分配指向已分配内存的指针。你正在做的事基本上等同于

int a = 5;
int b = 10;
a = b;

然后想知道为什么a不再等于5

使用赋值buf = asctime(gmtime(seconds)),您将丢失原始指针并导致内存泄漏。

asctime函数返回的是指向静态内部缓冲区的指针,它不应该传递给free

答案 1 :(得分:2)

你不应该对此感到惊讶,因为你已经从buf返回的内容中更改了指针malloc()的值。

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

使用未从free()返回的参数调用malloc()(或第二次调用它)是未定义的行为。

答案 2 :(得分:1)

您调用mallocmemset,它分配缓冲区并将其设置为零,但随后您使用buf的返回值覆盖asctime的值。当您致电free时,它会返回asctime的返回值,而非原始分配。这有三个问题:

  1. 您永远不会将使用malloc分配的缓冲区用于任何有用的目的,因此您不需要mallocmemset
  2. 您丢失了malloc返回的指针,因此您永远不会free它。你的过程泄漏了内存。
  3. 您尝试free来自asctime的返回值。 asctime的返回值不需要被释放,也不应该被释放。这会导致未定义的行为,在您的情况下是段错误。