为啥我的指针在删除后仍然指向一个地址?
Posted
技术标签:
【中文标题】为啥我的指针在删除后仍然指向一个地址?【英文标题】:Why does my pointer still point to an address after deleting it?为什么我的指针在删除后仍然指向一个地址? 【发布时间】:2020-11-02 21:41:09 【问题描述】:我正在学习 C++,但我无法理解与指针相关的某些行为。
我有一个简单的自定义对象,如下所示:
class Human
public:
//constructor here
private:
std::string name;
std::string address;
另一个具有人类指针实例变量类型的自定义对象:
class property
public:
Human * ppl;//pointer to the above human object
并运行这段代码:
Human * human = new Human("Mark", "address");// pointer address 0x123456 for example
Property * property = new Property();
property->ppl = human;//pass the pointer to property's instance variable
delete human;
human = NULL;//after deleting and setting it to NULL property.ppl still points to 0x123456
运行上面的代码后,property下的ppl实例变量仍然指向原来的内存地址,但是它的内容(名称和地址)都被清除了(现在是空字符串),我想知道为什么会这样?既然我传递了原始指针,为什么删除它并设置为NULL后,它仍然指向一个内存地址,但它的内容已经被清除了?
仅供参考:我使用 XCode 作为调试 IDE 和 C++11
【问题讨论】:
因为您将human
设置为空,而不是property.ppl
。这是两个独立的不相关变量。设置一个不会自动改变另一个。
因为 c++ 是一种没有垃圾收集器的语言。如果对某物的引用在内存中的某处,则由您将其全部设置为 NULL 或仅将其中一个设置为 NULL,或者不要在任何地方将其设置为 NULL。
指针只有一种方式。没有反向通道可以告诉指针他们指向的内容不再存在。
指针很难管理。这是从另一种语言 (C
) 遗留下来的。您最好不要在 C++ 中使用它们(指针)。当您必须进行动态分配时,您应该大部分时间使用自动对象或更高级的构造(如std::unique_ptr
)。
【参考方案1】:
看看这个更简单的例子:
int a = 5;
int b = a;
b = 45;
设置b
的值不会改变a
的值。同样,在代码中设置human
的值不会改变property->ppl
的值。
这个概念与delete
无关。但是,在指针的情况下,您必须非常小心,因为property.ppl
不再指向有效内存。您可以访问它,但可能会导致分段错误或其他一些非常难以调试的错误。
【讨论】:
【参考方案2】:为什么我的指针删除后仍然指向一个地址?
你错了。指针具有无效值。它既不指向它曾经指向的对象,也不指向任何其他对象。
我想知道为什么会这样?
行为就是这样,因为这是指定语言的方式。当一个对象被销毁并释放其内存时,所有指向该对象的指针(和引用)都将失效。
为什么删除它并设置为NULL后,它仍然指向...
您将human
设置为空。您永远不会将 property->ppl
设置为 null。这些是单独的对象(即使它们具有相同的值 - 即它们指向同一个对象)并且修改一个不会影响另一个。一个类似的情况:
int a = 1;
int b = a;
a = 2; // this does not modify b
【讨论】:
我不认为该值未指定。这只是一个无效的指针。 @cigien 在技术上很好地观察无效指针的值是实现定义的行为。我看不出有什么不同。 确实如此。我认为可以编辑答案以使其更清晰。 @cigien 我重写了以专注于主要问题。【参考方案3】:这两个对象一个是 Human 类型,另一个是 Property 类型
Human * human = new Human("Mark", "address");
Property * property = new Property();
占用为这些对象分配的不同范围的内存。
在此声明中
human = NULL;
正在更改对象human
占用的内存范围。
对象property
占用的内存没有改变。
如果类 Property 将按以下方式定义
class Property
public:
Human * &ppl;//pointer to the above human object
;
并且类 Property 的对象会像这样创建
Property * property = new Property human ;
然后确实将对象human
设置为NULL
或nullptr
对数据成员ppl
的影响,因为它具有引用类型。
【讨论】:
以上是关于为啥我的指针在删除后仍然指向一个地址?的主要内容,如果未能解决你的问题,请参考以下文章
删除我的指针后内存内容没有被删除(在一个简单的例子中)[重复]