我知道这已经被问了很多,但我看过的每一个例子似乎都不合适。在下面的代码中,如果我保留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;
}
答案 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)
您调用malloc
和memset
,它分配缓冲区并将其设置为零,但随后您使用buf
的返回值覆盖asctime
的值。当您致电free
时,它会返回asctime
的返回值,而非原始分配。这有三个问题:
malloc
分配的缓冲区用于任何有用的目的,因此您不需要malloc
或memset
malloc
返回的指针,因此您永远不会free
它。你的过程泄漏了内存。free
来自asctime的返回值。 asctime的返回值不需要被释放,也不应该被释放。这会导致未定义的行为,在您的情况下是段错误。