今天看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