没有malloc或calloc的free()函数

时间:2010-11-05 22:51:25

标签: c malloc calloc

快速提问

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

EI。

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

   //some processing here ....

   free(str);
}

我没有编译错误,但这是否有效或者它是否正确?

谢谢,

5 个答案:

答案 0 :(得分:10)

这一点都不正确:

  1. 您无法释放静态数组,例如char str[6]
  2. free()只应在你分配的内存(或NULL)上调用。

答案 1 :(得分:5)

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

答案 2 :(得分:3)

在非malloc'd变量上使用free会导致一般的Segfault。例如:

#include <stdlib.h>

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

$ gcc test.c -o test

$ ./test

分段错误

答案 3 :(得分:2)

free()使用前面分配的块前面的数据来管理堆。如果指向的内存未由堆分配函数(如malloc()或calloc())分配,那么块之前的数据将作为堆管理数据无意义。

某些库会检测到无效的堆数据,并且会出现运行时错误,否则行为是未定义的。在您稍后尝试分配更多内存之前,通常会忽略此类错误的后果。这可以使调试这样的错误非常困难。

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

答案 4 :(得分:0)


free(3)函数采用void *参数,因此您可以将任何类型的指针传递给它而不会出现编译时错误。但如果指针最初未由malloc(3)返回且以前从未返回free(3),则会发生错误。