c++指针复制指向同一个位置问题

时间:2021-12-18 10:53:38

今天看primer c++遇到一个问题:

#include <iostream>
#include <string>
#include <cstdio>
using namespace std;

class HasPtr
{
public:
    HasPtr(int *p, int i):ptr(p), val(i){}
	int *get_ptr() const {return ptr;}
	int get_int() const {return val;}
	void set_ptr(int *p) {ptr = p;}
	void set_int(int v) {val = v;}
	int get_ptr_val() const { return *ptr;}
	void set_ptr_val(int val) const {*ptr = val;}

public:
	int *ptr;
	int val;
};
int main(int argc, char *argv[])
{
    int obj = 0;
	HasPtr ptr1(&obj, 42);
	HasPtr ptr2(ptr1);
        //此时ptr1的val 和 ptr 与ptr2 的地址是一致的
	ptr1.set_int(34); //复制一个算术值时,副本独立于原版,可以改变一个副本而不改变另一个
	cout << ptr1.get_int() << " " << ptr2.get_int() << endl;
	ptr1.set_ptr_val(45); //复制指针时,地址值是可区分的,但指针指向同一基础对象。如果在任一对象上调用 set_ptr_val,则二者的基础对象都会改变
	cout << *(ptr1.ptr) << " " << *(ptr2.ptr)<<endl;
	//
	int *intp = new int(10);
	HasPtr ptr3(intp, 20);
	delete intp;
	intp = NULL;
	// ptr3.set_ptr_val(22);  
	ptr3.set_ptr(ptr3.ptr);
	cout << *(ptr3.ptr)<<endl;
    return 0;
}

此时打印结构为:

34 42
45 45
0

如果这样:

ptr3.set_ptr_val(22);  
// ptr3.set_ptr(ptr3.ptr);

打印结果:
34 42
45 45
22

c++primer的官方说法:
int *ip = new int(42); // dynamically allocated int initialized to 
42 
HasPtr ptr(ip, 10); // Has Ptr points to same object asip does 
delete ip; // object pointed to by ip is freed
ptr.set_ptr_val(0); // disaster: The object to which Has Ptr points 
was freed! 

修正: delete以后,那块儿内存依然存在,但是以后再new的时候,有可能分配给别人,ptr里面的指针依然可以访问这块内存,但是别人并不知道你会修改这个值,所以书中说是disaster。这种问题是最难调试的
指针虽然释放内存依旧可一个使用。但是避免野指针的发生一定要先delete 在设置为NULL