问题描述
我正在学习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
运行上述代码后,属性下的ppl实例变量仍指向原始内存地址,但其内容(名称和地址)都被清除(现在为空字符串),我想知道为什么这是行为吗?自从我传递原始指针以来,为什么删除它并将其设置为NULL之后,它仍然指向内存地址,但是其内容已被清除?
仅供参考:我正在使用XCode作为调试IDE和C ++ 11
解决方法
看这个简单的例子:
int a = 5;
int b = a;
b = 45;
设置b
的值不会不更改a
的值。同样,在代码中设置human
的值不会更改property->ppl
的值。
此概念与delete
无关。但是,对于指针,您必须非常小心,因为property.ppl
不再指向有效内存。您可以访问它,但可能会导致分段错误或其他一些很难调试的错误。
为什么我的指针在删除后仍然指向一个地址?
您误会了。指针的值无效。它既不指向它曾经指向的对象,也不指向任何其他对象。
我想知道为什么会这样吗?
行为就是这样,因为这是指定语言的方式。当一个对象被销毁并释放其内存时,所有指向该对象的指针(和引用)均无效。
为什么删除它并将其设置为NULL后,它仍然指向...
您将human
设置为null。您永远不会将property->ppl
设置为null。这些是单独的对象(即使它们具有相同的值-即它们指向同一对象),并且修改一个对象不会影响另一个对象。类似的情况:
int a = 1;
int b = a;
a = 2; // this does not modify b
,
这两个对象的类型分别是“人”类型和另一个“属性”类型
Human * human = new Human("Mark","address");
Property * property = new Property();
为这些对象分配了不同程度的内存。
在此声明中
human = NULL;
正在更改对象human
占用的内存范围。
对象property
占用的内存未更改。
如果可以通过以下方式定义属性类
class Property {
public:
Human * &ppl;//pointer to the above human object
};
和属性类的对象将被创建为
Property * property = new Property { human };
然后确实将对象human
设置为NULL
或nullptr
对数据成员ppl
有影响,因为它具有引用的类型。