不应该free()接受一个(void * const)作为输入arg

时间:2016-03-08 05:59:10

标签: c pointers free

我试图理解免费的工作。 是否在标准中定义free()不会改变它传递的指针?

3 个答案:

答案 0 :(得分:6)

在标准C中,参数传递是按值。因此,函数不能更改其参数的值(这不是free特有的)。每次通话都是call by value。如果在函数内部更改某个参数,则只更改该参数的本地副本(例如,在某些机器寄存器中),并且调用者看不到任何更改。

如果你想改变某些东西,你会将那个东西的地址作为一个值传递,你将取消引用该指针。

因此free不会更改传递给它的指针,但您需要确保永远不再使用该指针。否则,那是undefined behavior。一种常见的风格是代码free(ptr), ptr=NULL;(以便通过segmentation fault进行任何进一步的ptr访问都会崩溃。

实际上,C standard library的大多数实现都标记了free - d区域,可以在将来malloc重用。但有时(特别是在释放大内存区域时)内存被释放到内核(例如,在Linux上由munmap(2)释放)。内存区域真正发生的是特定于实现的。

阅读C dynamic memory allocation&的wikipages virtual address space

另请参阅一些free software C标准库实现的源代码(例如Linux上的大多数libc,例如musl-libcGNU libc ...)。使用所有警告编译代码&调试信息(例如gcc -Wall -Wextra -g如果使用GCC ...),则使用valgrind来搜寻memory leak个错误。

答案 1 :(得分:1)

const存储类型告诉编译器一旦分配(动态或静态),您不打算修改内存块。释放内存正在修改它。

答案 2 :(得分:1)

free是否更改输入参数或与调用代码无关。调用代码仍然有指针。它类似于将int传递给函数。被调用的函数可能会更改变量,但它是副本的更改,而不是原始的。

void foo(int i)
{
   i += 2;
}

void bar()
{
   int i = 10;
   foo(i);
}

此处,对i中的foo所做的更改不会更改`bar中i的值。

类似地,

void free(void* ptr)
{
   // Do the needful to deallocate
   ...
     ptr = NULL;
}

void test()
{
    char* p = malloc(10);
    ...
    free(p);
}

此处,对ptr中的free所做的更改不会更改test中指针的值。因此,使free的参数为void* const类型没有多大意义。