CPtrArray的使用陷阱

MFC提供了一个类似于C++ vector的ATL模版,可以实现类似于vector的功能,主要方法有如下:

    void RemoveAll();
    // Accessing elements
    void* GetAt(INT_PTR nIndex) const;
    void SetAt(INT_PTR nIndex, void* newElement);
    const void** GetData() const;
    void** GetData();
INT_PTR Add(void* newElement);
    void RemoveAt(INT_PTR nIndex, INT_PTR nCount = 1);
    void InsertAt(INT_PTR nStartIndex, CPtrArray* pNewArray);

也就是基本上的添加单个元素,插入和删除指定序列存储的元素,获得指定序号的元素,删除全部元素。

一般常用的添加元素的方式为:

CPtrArray m_testarr;
infodata m_infodata;
infodata* pindata = new infodata;
m_testarr.Add((infodata*)pindata);

即通过 new一个元素对象,然后通过add方法插入的CPtrArray的队列中;

那么当使用完后删除,相信很多人的第一想法就是通过调用RemoveAll()方法。

我们看removeall的实现:(为了方便,只截取了核心部分)

    if (nNewSize == 0)
    {
        // shrink to nothing
        if (m_pData != NULL)
        {
            for( int i = 0; i < m_nSize; i++ )
                (m_pData + i)->~TYPE();
            delete[] (BYTE*)m_pData;
            m_pData = NULL;
        }
        m_nSize = m_nMaxSize = 0;
    }

也就是说removeall里面会进行delete操作,那么事实是这样吗?

我们调试看看:

上述

infodata* pindata = new infodata;

m_testarr.Add((infodata*)pindata);

调试产生的结果如下:

执行removeall操作:

pindata = (infodata*)m_testarr.GetAt(0);

m_testarr.RemoveAll();

我们可以发现,CPtrArray的m_pdata内容为空了,但是元素指针pindata的地址却没有为0。

所以实际上removeall方法并没有释放我们之前new分配的元素。

这是因为CPtrArray的m_pdata其实是一个二级指针,他存储每个元素的地址,removeall只是释放了m_pdata。

所以需要在removeall之前通过delete释放相应元素

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值