4

快速提问

您可以使用 free() 函数而不必事先调用 malloc 吗?

艾。

void someFunc( void )
{
   char str[6] = {"Hello"};

   //some processing here ....

   free(str);
}

我没有得到任何编译错误,但这是否有效或完全正确?

谢谢,

4

5 回答 5

10

这根本不正确:

  1. 您不能释放静态数组,例如char str[6].
  2. free() 只能在您分配的内存(或 NULL)上调用。
于 2010-11-05T22:52:35.000 回答
5

当您调用 malloc() 或任何其他分配函数时,将在堆上分配内存。这是唯一可以释放的内存。当您声明一个静态字符串时,正如您在示例中所做的那样,该字符串在编译时分配到另一个内存段中。分配在堆栈上的str指针本身也是如此,因此也无法释放。

于 2010-11-05T22:56:00.473 回答
3

在非 malloc 变量上使用 free 通常会导致 Segfault。例子:

#include <stdlib.h>

int main()
{
  char str[6] = {"Hello"};
  free(str);
}

$ gcc test.c -o 测试

$ ./测试

分段故障

于 2010-11-05T22:54:46.480 回答
3

free() 使用附加到分配块的数据来管理堆。如果指向的内存不是由诸如 malloc() 或 calloc() 之类的堆分配函数分配的,那么块之前的数据将作为堆管理数据毫无意义。

一些库会检测到无效的堆数据并产生运行时错误,否则行为未定义。在您稍后尝试分配更多内存之前,通常不会注意到此类错误的后果。这会使调试此类错误变得非常困难。

您不会收到编译器错误,因为它不是语法错误并且在编译时无法检测到。编译器不知道库函数的语义。它只知道 malloc() 返回一个 void* 并且 free() 接受一个 void*;在编译时无法知道指针是否指向动态分配的块,因为根据定义,内存是在运行时分配的。此外,可以在运行时修改指针以指向任何内存类型,或者可以使用别名 - 复制到另一个指针,然后通过第二个指针释放。如果您期望出现错误消息,您期望很多编译器;但是,如果可能发生此类错误,某些静态分析工具可能会发出警告,而 valgrind 等动态分析工具可能会在测试期间以及是否实际发生错误时检测到错误。

于 2010-11-05T23:34:09.030 回答
0


free(3)函数带有一个void *参数,因此您可以将任何类型的指针传递给它而不会出现编译时错误。但是,如果指针最初不是malloc(3)free(3).

于 2010-11-05T22:59:48.907 回答