看不见的内存泄漏? - malloc 和 strcpy

Invisible memory leak? - malloc and strcpy

我编译了我的代码,前两次它崩溃了。我没有改变任何东西并再次编译,第三次和第四次编译过程运行良好,没有任何崩溃。

前两次崩溃并没有立即发生,它已经打印了我的printf语句,立即被强行关闭。

这是我的代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
  char testString[] = "Yiu Rules";
  char* destString = (char*)malloc(sizeof(strlen(testString))*2);

  strcpy(destString, testString);

  printf("%s", destString);

  free(destString);

  return 0;

}

有什么想法吗?

sizeof(strlen(testString)) 不是你想的那样。您计算 strlen 返回值的大小(以字节为单位),即 size_t.

只需使用 strlen(testString).

这就是 strcpy 不是安全函数的原因,您应该使用 strncpy

您分配了 sizeof(strlen(testString)) * 2 字节的内存。这似乎没有道理。 sizeof(strlen(testString)) * 2sizeof(size_t) * 2,这通常是你的字符串不够用。

sizeof(size_t) * 2 在 64 位或 32 位平台上通常分别是 16 或 8 字节的内存。在 64 位平台上,您的代码将 "survive",因为您的字符串适合 16 个字节。但在 32 位平台上它不适合,它会溢出分配的内存并损坏堆。

这个

char* destString = malloc(strlen(testString) * 2);

会有些道理(如果你想尝试过度分配内存),但我不清楚 sizeof 的来源和原因。

sizeof(strlen(testString)) 确实不正确,但它仍然显示了一个很好的做法,即使用应用于 char 类型的 sizeof 运算符。在您的情况下,您在 size_t 上使用 sizeof 这不是您想要的,strlen 已经为您提供了要传递给 malloc 的字节数,但是如果您也想使用 sizeof,这是一种正确的方法这样做:

(char *)malloc(sizeof(char) * strlen(testString) * 2 + 1).

注意 malloc 末尾的 + 1:strlen 不计算它计算长度的字符串的终止 NULL 字节。然后你的 strcpy 可能会工作,但你最终也可能会遇到总线错误或某种错误,因为你试图将 \0 (在 strcpy 中)附加到内存的未保留部分。

此外,你的 malloc 可能 return 你已经使用了内存区域(但它很少发生在像你提供的那样的短程序中)所以你可以在分配后立即使用 bzero 以确保你正在清理内存。