在 C 中释放指向 malloc 内存的指针的副本

Freeing a copy of a pointer to malloc'd memory in C

似乎无法在其他地方找到我的问题的答案。

考虑代码:

int *ptr = malloc (sizeof (*ptr));

int *dummyPtr = ptr;

free (dummyPtr);

printf ("ptr: %p, dummy: %p\n", ptr, dummyPtr);

据我了解,free() 接受一个指针并使其指向 NULL 又名 (nil)。即,指针被取消引用并且指向任何地方。这意味着指针指向的内存被有效擦除。

这个问题分为两个部分:

  1. 如果我运行上面的代码,dummyPtr似乎仍然指向内存中的地址而不是(nil)。为什么?
  2. ptr 会怎样?它仍然指向那个内存块还是它也被取消引用了?

我已经 运行 这段代码和一些变体几次,但结果相互矛盾。有时只有副本受到影响,有时两者都会受到影响。有时指向的值甚至设置为零!

坦率地说,我不知道发生了什么。 (我是 运行ning Debian,如果这有影响的话。)

The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. If ptr is NULL, no operation is performed.

您从哪里得知 free 将指针设置为 NULL -- 它没有。如果您想重用指针,那是您的工作。如果您不重复使用它,那么它指向的位置没有任何区别。

Dummyptr 仍然保留旧的内存位置。在 free 之后 prt 和 dummyptr 都被用掉了,不应该被取消引用,因为这会导致未定义的行为。

free 不会将指针设置为 NULL 或擦除任何内存。相反,它将指针指向的内存块标记为空闲(即未分配)。

调用 free(dummyPtr) 后,ptrdummyPtr 现在都是无效指针,因为它们没有指向已分配的内存块。

您的 printf 行使用无效指针导致未定义的行为。当 undefined behaviour 发生时,所有赌注均无效。


标准参考:C11 6.2.4/2

The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.

附件 J.2:

The behavior is undefined in the following circumstances:

  • The value of an object with automatic storage duration is used while it is indeterminate

要理解请查看 free()

的原型
void free(void *ptr)

函数不可能将 ptr 更改为指向 NULL,即使它想要这样做,ptr 只是被复制到函数中,因此它只能释放 ptr 指向的内容。

为了自由改变它需要一个像

这样的原型
void free(void **ptr)

一旦使用 ptr 指向的内存在指针上调用 free 是未定义的行为,因为内存已返回到 OS。