| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 895 人关注过本帖
标题:求助:智能指针的一个实现,不知为何在析构时出现指针无效?
只看楼主 加入收藏
wangfangjin
Rank: 1
等 级:新手上路
帖 子:29
专家分:5
注 册:2010-7-13
结帖率:80%
收藏
已结贴  问题点数:10 回复次数:4 
求助:智能指针的一个实现,不知为何在析构时出现指针无效?
程序代码:
using std::endl;

#include <string>

#include <cstddef>
using std::size_t;
/* smart pointer class: takes ownership of the dynamically allocated

 *                      object to which it is bound

 * User code must dynamically allocate an object to initialize a HasPtr

 * and must not delete that object; the HasPtr class will delete it
*/
//private class for use by HasPtr only
class U_Ptr {
    friend class HasPtr;
    int *ip;//save raw point
    size_t use;//save num
    U_Ptr(int *p): ip(p), use(1) { }
    ~U_Ptr() { delete ip; cout<<"ip已经被释放!"<<endl;}
};

class HasPtr {
public:
    // HasPtr owns the pointer; p must have been dynamically allocated
    HasPtr(int *p, int i): ptr(new U_Ptr(p)), val(i) { }

    // copy members and increment the use count
    HasPtr(const HasPtr &orig):
       ptr(orig.ptr), val(orig.val) { ++ptr->use; }
    HasPtr& operator=(const HasPtr&);

    // if use count goes to zero, delete the U_Ptr object
    ~HasPtr() { if (--ptr->use == 0) delete ptr; } 

    friend ostream& operator<<(ostream&, const HasPtr&);
    // copy control and constructors as before

    // accessors must change to fetch value from U_Ptr object
    int *get_ptr() const { return ptr->ip; }
    int get_int() const { return val; }

    // change the appropriate data member
    void set_ptr(int *p) { ptr->ip = p; }
    void set_int(int i) { val = i; }

    // return or change the value pointed to, so ok for const objects
    // Note: *ptr->ip is equivalent to *(ptr->ip)
    int get_ptr_val() const { return *ptr->ip; }
    void set_ptr_val(int i) { *ptr->ip = i; }
private:
    U_Ptr *ptr;        // points to use-counted U_Ptr class
    int val;
};

HasPtr& HasPtr::operator=(const HasPtr &rhs)
{
    ++rhs.ptr->use;     // increment use count on rhs first
    if (--ptr->use == 0)
         delete ptr;    // if use count goes to 0 on this object, delete it
    ptr = rhs.ptr;      // copy the U_Ptr object
    val = rhs.val;      // copy the int member
    return *this;
}

ostream& operator<<(ostream &os, const HasPtr &hp)
{
    os << "*ptr: " << hp.get_ptr_val() << "\tval: " << hp.get_int() << endl;
    return os;
}

int main()
{
    int obj = 0;

    HasPtr ptr1(&obj, 42);
    HasPtr ptr2(ptr1);
    cout << "(1) ptr1: " << ptr1 << endl << "ptr2: " << ptr2 << endl;

    ptr1.set_ptr_val(42); // sets object to which both ptr1 and ptr2 point
    ptr2.get_ptr_val();   // returns 42

    cout << "(2) ptr1: " << ptr1 << endl << "ptr2: " << ptr2 << endl;

    ptr1.set_int(0);   // changes s member only in ptr1
    ptr2.get_int();    // returns 42
    ptr1.get_int();    // returns 0

    cout << "(3) ptr1: " << ptr1 << endl << "ptr2: " << ptr2 << endl;
    system("pause");
    return 0;
}
搜索更多相关主题的帖子: 指针 智能 
2010-10-13 18:46
hahayezhe
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:湖南张家界
等 级:贵宾
威 望:24
帖 子:1386
专家分:6999
注 册:2010-3-8
收藏
得分:5 
那里抄袭的代码

你释放的时候 判断下
如果ip==NULL 就不需要释放了

再者你那是智能指针?
我还以为是auto_ptr或者share_ptr呢
2010-10-13 20:42
wangfangjin
Rank: 1
等 级:新手上路
帖 子:29
专家分:5
注 册:2010-7-13
收藏
得分:0 
回复 2楼 hahayezhe
当然不是,只是利用智能指针实现的思想,来控制指针共享一个基础对象而已
2010-10-14 08:55
wangfangjin
Rank: 1
等 级:新手上路
帖 子:29
专家分:5
注 册:2010-7-13
收藏
得分:0 
以下是引用hahayezhe在2010-10-13 20:42:21的发言:

那里抄袭的代码

你释放的时候 判断下
如果ip==NULL 就不需要释放了

再者你那是智能指针?
我还以为是auto_ptr或者share_ptr呢
仍然是同样的错误:
jinjianye@ubuntu:~$ g++ -o smartptr smart-ptr.cpp
程序代码:
jinjianye@ubuntu:~$ ./smartptr
(1) ptr1: *ptr: 10    val: 42

ptr2: *ptr: 10    val: 42

2
(2) ptr1: *ptr: 42    val: 42

ptr2: *ptr: 42    val: 42

(3) ptr1: *ptr: 42    val: 0

ptr2: *ptr: 42    val: 42

*** glibc detected *** ./smartptr: free(): invalid pointer: 0x0000000000602070 ***
======= Backtrace: =========
/lib/libc.so.6[0x7f59dafdf2f6]
/lib/libc.so.6(cfree+0x6c)[0x7f59dafe3c6c]
./smartptr[0x400d99]
./smartptr[0x400e86]
./smartptr[0x400ccc]
/lib/libc.so.6(__libc_start_main+0xfd)[0x7f59daf87abd]
./smartptr[0x400939]
======= Memory map: ========
00400000-00402000 r-xp 00000000 07:01 104                                /home/jinjianye/smartptr
00601000-00602000 r--p 00001000 07:01 104                                /home/jinjianye/smartptr
00602000-00603000 rw-p 00002000 07:01 104                                /home/jinjianye/smartptr
01d25000-01d46000 rw-p 00000000 00:00 0                                  [heap]
7f59d4000000-7f59d4021000 rw-p 00000000 00:00 0
7f59d4021000-7f59d8000000 ---p 00000000 00:00 0
7f59daf69000-7f59db0cf000 r-xp 00000000 07:00 5736                       /lib/libc-2.10.1.so
7f59db0cf000-7f59db2cf000 ---p 00166000 07:00 5736                       /lib/libc-2.10.1.so
7f59db2cf000-7f59db2d3000 r--p 00166000 07:00 5736                       /lib/libc-2.10.1.so
7f59db2d3000-7f59db2d4000 rw-p 0016a000 07:00 5736                       /lib/libc-2.10.1.so
7f59db2d4000-7f59db2d9000 rw-p 00000000 00:00 0
7f59db2d9000-7f59db2ef000 r-xp 00000000 07:00 7619                       /lib/libgcc_s.so.1
7f59db2ef000-7f59db4ee000 ---p 00016000 07:00 7619                       /lib/libgcc_s.so.1
7f59db4ee000-7f59db4ef000 r--p 00015000 07:00 7619                       /lib/libgcc_s.so.1
7f59db4ef000-7f59db4f0000 rw-p 00016000 07:00 7619                       /lib/libgcc_s.so.1
7f59db4f0000-7f59db572000 r-xp 00000000 07:00 6634                       /lib/libm-2.10.1.so
7f59db572000-7f59db772000 ---p 00082000 07:00 6634                       /lib/libm-2.10.1.so
7f59db772000-7f59db773000 r--p 00082000 07:00 6634                       /lib/libm-2.10.1.so
7f59db773000-7f59db774000 rw-p 00083000 07:00 6634                       /lib/libm-2.10.1.so
7f59db774000-7f59db866000 r-xp 00000000 07:02 383                        /usr/lib/libstdc++.so.6.0.13
7f59db866000-7f59dba66000 ---p 000f2000 07:02 383                        /usr/lib/libstdc++.so.6.0.13
7f59dba66000-7f59dba6d000 r--p 000f2000 07:02 383                        /usr/lib/libstdc++.so.6.0.13
7f59dba6d000-7f59dba6f000 rw-p 000f9000 07:02 383                        /usr/lib/libstdc++.so.6.0.13
7f59dba6f000-7f59dba84000 rw-p 00000000 00:00 0
7f59dba84000-7f59dbaa3000 r-xp 00000000 07:00 5313                       /lib/ld-2.10.1.so
7f59dbc82000-7f59dbc85000 rw-p 00000000 00:00 0
7f59dbc9e000-7f59dbca2000 rw-p 00000000 00:00 0
7f59dbca2000-7f59dbca3000 r--p 0001e000 07:00 5313                       /lib/ld-2.10.1.so
7f59dbca3000-7f59dbca4000 rw-p 0001f000 07:00 5313                       /lib/ld-2.10.1.so
7fffd2f16000-7fffd2f2b000 rw-p 00000000 00:00 0                          [stack]
7fffd2fe7000-7fffd2fe8000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted
2010-10-14 09:22
missiyou
Rank: 5Rank: 5
等 级:贵宾
威 望:16
帖 子:531
专家分:218
注 册:2007-10-9
收藏
得分:5 
int obj = 0;  // 栈内定义

    HasPtr ptr1(&obj, 42); //传指针进去。如果int *ip 不从堆申请内存,直接,ip(&obj) 是没有放内存效果,调试的时候是会有点问题。
    应该是 ip = new int(); ip = p;   将这句修改U_Ptr(int *p): ip(p), use(1) { }

   我写的测试代码:
    int *obj = new int();
    U_Ptr  *u = new U_Ptr(obj);
    delete u;
    // int test1;
    // cout << "test: " << test1 << endl;
    HasPtr ptr1(obj, 42);
    int *obj1 = new int(1);
    HasPtr ptr2(obj1, 33); // HasPtr ptr2 = ptr1; = HasPtr ptr2(ptr1) 这个就调用了 HasPtr(const HasPtr &orig)这个函数,
    ptr2 = ptr1;//这里调用重载函数, 就会输出"p已经被释放!

   test:
    int main(){
       int obj = 0;
       HasPtr ptr1(&obj, 42);
     }//这样定义,就会出现内存“ip已经被释放!”

  so:
     之所以没出“p已经被释放!” 是因为引用计数指针是内部共享, 同时已经加到2了. ptr1 与ptr2 引用计数都是2

[ 本帖最后由 missiyou 于 2010-10-18 13:44 编辑 ]
2010-10-18 13:33
快速回复:求助:智能指针的一个实现,不知为何在析构时出现指针无效?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015861 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved