class MyClass
{
friend void friend_test(MyClass& p);//友元
public:
MyClass(int age,string name) {
NAME = name;
M_nume_age = new int(age);//堆区创建的空间
}
~MyClass(){
if (M_nume_age!=NULL){
delete M_nume_age;
M_nume_age = NULL;
}
}
public:
string NAME;
private:
int* M_nume_age;
};
void friend_test(MyClass& p) { //全局函数 ->静态区
cout << p.NAME<<"年龄: " << *p.M_nume_age << endl;
}
void test01() {
MyClass P1(10, "P1");
friend_test(P1);
cout << endl;
MyClass P2(20,"P2");
friend_test(P2);
cout<<endl;
P2 = P1;
friend_test(P2);
}
int main() {
test01(); //局部函数
system("pause");
return 0;
}
//1.析构函数
if (M_nume_age!=NULL){
delete M_nume_age;
M_nume_age = NULL;
}
堆区P2先析构释放让P2.M_name_age=0x000...了么 这不就是空么?
为什么P1释放的时候if (M_nume_age!=NULL)还会判断不等于空
难道NULL!=0x0000...
希望哪位道友给我说道说道
参考GPT和自己的思路:首先,NULL和0是等价的,都表示空指针。在if (M_nume_age!=NULL)判断中,其实就是在判断指针M_nume_age是否为空(即是否指向了一个有效的内存空间),如果为空才会跳过delete语句。在析构函数执行前,P1和P2的M_nume_age都指向一个有效的内存空间,但是在P2被赋值给P1时,P1的M_nume_age指向的空间被释放,所以在P1析构函数执行时需要判断M_nume_age是否为空,因为在P2赋值给P1之后,可能出现M_nume_age指向已经被释放的空间的情况。
首先,哪里有赋值成0了,我怎么没看到相关代码
其次,地址是0代表内存地址是0,虽然是个野指针但是也是个合法的地址,不是NULL
经典的 浅拷贝 和 double free 问题
这里的问题在于, 没有区分到指针的值 和指针指向的内存地址
P2.M_num_age 与 P1.M_num_age 指向同一片内存,比如 0x1234
P2 析构, P2.M_num_age 的指针被置为空
但是 P1.M_num_age 的指针 还是指向 0x1234,是 0x1234 被释放了,和 P2.M_num_age 置为空了,
除非你在析构的时候再赋一次值
修改指针的值 通常我们的函数需要传 二级指针,或者指针的引用。 : )