【问题标题】:Will a pointer p1 be accessible after freeing another pointer p2 containing the same address as p1?在释放包含与 p1 相同地址的另一个指针 p2 后,指针 p1 是否可以访问?
【发布时间】:2022-01-25 19:12:08
【问题描述】:

如果您将相同地址的指针分配给具有相同结构的另一种类型定义的另一个指针,那么程序可能会出现分段错误,然后您释放前一个并仅使用最后分配的同一个地址?

#include <stdio.h>
#include <stdlib.h>

struct Class{
 int data;
 struct Class *next;
}key;

int main(){
 key *newclass = malloc(sizeof(*newclass));
 newclass->data = 5;
 newclass->next = NULL;
 
 key *newclass2;
 newclass2 = newclass;
 
 newclass = NULL;
 free(newclass);

 printf("%d", newclass2->data);
 
 return 0;
}

【问题讨论】:

  • 是的,这是非法的。两个指针都指向同一个内存,即freed。之后,两个指针都指向一个无效的位置。
  • 实际上,free(newclass); 调用不会执行任何操作...因为前面的 newclass = NULL; 行。而newclass2 仍将指向原始分配的内存。
  • free() 释放其参数指向的内存(如果有)。这使得指向已释放区域的 all 指针(in)无效。它与变量无关,如果有的话,free() 的参数是从中获取的。当然free() 本身并没有看到这一点。
  • 你不是free 指针,你是free 内存。指针只是告诉free是哪个内存。
  • 可能值得研究“对象”(与 OOP 对象无关)和“存储持续时间”(自动、静态、线程、动态)的 C 概念。

标签: c memory linked-list


【解决方案1】:

对于初学者来说,结构定义中似乎存在拼写错误。我想你的意思是

typedef struct Class{
 int data;
 struct Class *next;
}key;

这次分配之后

 newclass2 = newclass;

两个指针都指向同一个动态分配的内存。

然后指针newclass被重新赋值为NULL

 newclass = NULL;

所以调用函数free为一个空指针

 free(newclass); 

没有效果。

指针newclass2 仍然指向动态分配的内存,您应该释放它,然后不再需要它。

 free(newclass2);

如果您要删除此作业

 newclass = NULL;

然后用这个指针调用free之后

 free(newclass); 

存储在指针newclass2 中的值将无效,您不能使用它来访问已释放的内存。

但是作为局部变量的两个指针仍然存在,您可以为它们分配新值。

【讨论】:

  • 对于初学者,你确实阅读了原始代码......
  • @wildplasser 出了什么问题?
  • 感谢 Vlad 的解释,我不知道为什么我确实将这个指针分配给 NULL,但是在释放指针 newclass 后,通过以正确的方式调用 free,所以内存堆不可用不再,但指针仍然可以指向其他可访问的地方?
  • @Hynem 如果您将使用可访问的地址重新分配它们,那么它们将具有有效值。否则在释放分配的内存后,指针的值无效(我假设您在释放内存之前没有将指针设置为 NULL)
【解决方案2】:

指针只是内存的索引。它指向的不是“数据”本身。这是它指向的内存的索引。

我在这里做一个假设,然后说

newclass = NULL;

是错误的,因为如果不是,你现在有内存泄漏。

如果您正确管理所有这些指针,那么让多个指针指向同一内存并没有错(纯粹谈论技术性,而不是就这是否是一种不好的做法发表任何声明。)。 问题在于,如果您释放了该内存并且忘记管理其中一个指针并尝试通过该指针对该释放的内存块执行操作,那么这绝对是一个问题。

指针指向的内存块被释放的事实并没有释放“指针”本身。您仍然可以将指针用于各种东西;从指针算术到使它们指向不同的内存块。黄金法则是不对指针之前索引的内存地址进行任何内存操作。

【讨论】:

  • newclass = NULL: 分配很奇怪,但既不是错误也不是内存泄漏。还有另一个指针newclass2,它指向该地址,并且可以使用free(newclass2) 释放内存。该分配还意味着free(newclass); 调用没有任何用处。
  • 当然,我们仍然可以通过另一个指针释放内存,但是由于 OP 后来没有释放它,这就是我说这是内存泄漏的原因。我说这是基于 OP 发布的代码的内存泄漏。同样是的, free(NULL) 正如你所说的那样什么都不做。参考:en.cppreference.com/w/c/memory/free
猜你喜欢
  • 1970-01-01
  • 2013-09-26
  • 2022-12-09
  • 2016-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-02
  • 1970-01-01
相关资源
最近更新 更多