简体   繁体   English

释放指向C中已分配内存的指针的副本

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

Couldn't seem to find an answer to my question elsewhere. 似乎在其他地方找不到我的问题的答案。

Consider the code: 考虑一下代码:

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

int *dummyPtr = ptr;

free (dummyPtr);

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

As I understand it, free() takes in a pointer and makes it point to NULL aka (nil) . 据我了解, free()接受一个指针,并使其指向NULL aka (nil) Ie, the pointer is dereferenced and points nowhere. 即,指针被取消引用并且指向无处。 This means that the memory pointed to by the pointer is effectively erased. 这意味着指针所指向的内存将被有效擦除。

Two parts to this question: 这个问题分为两部分:

  1. If I run the above code, dummyPtr still seems to point to an address in memory and not (nil) . 如果我运行上面的代码, dummyPtr似乎仍然指向内存中的地址,而不是(nil) Why? 为什么?
  2. What happens to ptr ? ptr怎样? Will it still point to that block of memory or has it been dereferenced too? 它是否仍指向该内存块或是否也已取消引用?

I've run this code and some variants a few times with conflicting results. 我已经运行了这段代码和一些变体几次,但结果相互矛盾。 Sometimes only the copy is affected, sometimes both. 有时只影响副本,有时两者都受影响。 Sometimes the values pointed to are even set to zero! 有时,指向的值甚至设置为零!

Frankly, I have no idea what's going on. 坦白说,我不知道发生了什么。 (I'm running Debian, if that makes a difference.) (如果正在运行,我正在运行Debian。)

free does not set the pointer to NULL , or erase any memory. free不会将指针设置为NULL,也不会擦除任何内存。 Instead, it marks the memory block that the pointer is pointing to as being free (ie not allocated). 相反,它会将指针指向的内存块标记为空闲(即未分配)。

After the call to free(dummyPtr) , both ptr and dummyPtr are now invalid pointers, because they do not point to an allocated block of memory. 在调用free(dummyPtr)ptrdummyPtr现在都是无效的指针,因为它们不指向已分配的内存块。

Your printf line causes undefined behaviour by using an invalid pointer. 您的printf行使用无效的指针导致未定义的行为。 When undefined behaviour has happened, all bets are off. 当发生未定义的行为时 ,所有赌注都关闭。


Standard references: C11 6.2.4/2 标准参考: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. 当指针所指向的对象(或刚过去的对象)达到其生命周期的终点时,指针的值将变得不确定。

Annex J.2: 附件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 具有自动存储持续时间的对象的值在不确定时使用

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(). free()函数释放ptr指向的内存空间,该内存空间必须已由先前对malloc(),calloc()或realloc()的调用返回。 Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. 否则,或者如果之前已经调用过free(ptr),则会发生未定义的行为。 If ptr is NULL, no operation is performed. 如果ptr为NULL,则不执行任何操作。

Where do you get that free sets the pointer to NULL -- it doesn't. 您从何处获得了free将指针设置为NULL呢? That is your job if you want to reuse the pointer. 如果您想重用指针,那就是您的工作。 If you are not reusing it, then is makes no difference where it points. 如果您不重用它,则它所指向的位置没有任何区别。

To understand look at the prototype for free() 要了解,请查看free()的原型

void free(void *ptr)

It is not possible for the function to change ptr to point to NULL even if it wanted that, ptr is just copied to the function so it can only free what ptr points to. 即使该函数希望将函数的ptr更改为指向NULL,也无法将其更改为空,因为ptr只是复制到该函数中,因此只能释放ptr指向的内容。

In order for a free to change that it would need a prototype like 为了自由更改,它需要一个原型,例如

void free(void **ptr)

Once free has been called on the pointer using the memory that ptr pointed to is undefined behavior since the memory has been returned to the OS. 一旦使用ptr指向的内存在指针上调用了free,则该行为是未定义的行为,因为该内存已返回给OS。

Dummyptr still holds the old memory location. Dummyptr仍然保留旧的内存位置。 After the free both prt and dummyptr become spent and should not be dereferenced as this will result in undefined behaviour. 释放之后,prt和dummyptr都将耗尽,不应取消引用,因为这将导致不确定的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM