1

可能重复:
如何正确删除指针?

std::vector用来将一组对象放入其中以备后用,我DETAIL* pPtr = new DETAIL用来创建指针,然后将其插入向量中。

DETAIL 的结构

struct DETAIL {
    int nRef;
    short sRandom;
};

这是删除和擦除向量中的指针的最佳方法,不会留下内存泄漏的空间吗?

while(Iter1 != m_Detail.end())
{
    if((*Iter1)->nRef == m_SomeVar)    
    {
        delete  *Iter1;
        m_Detail.erase(Iter1);
        break;
    }

    Iter1++;
}
4

5 回答 5

9

不要将原始指针放入 . vector,而是使用智能指针,例如std::shared_ptr. 那么就不需要了delete,简单erase的指针 fromvector和指向的对象就会被自动删除。

于 2012-06-01T18:30:42.507 回答
0

DETAIL* pPtr = new DETAIL用来创建指针

这是您的第一个错误,您正在获取资源(来自 freestore 的内存和在该内存中构造的对象),而不是初始化将获取所有权并保证释放您获取的资源的对象。解决第一个错误的成语称为Resource Acquisition Is Initialization

它应该是这样的:

std::shared_ptr<DETAIL> pPtr(new DETAIL);

或者更好:

std::shared_ptr<DETAIL> pPtr = std::make_shared<DETAIL>();

或在 C++03 中替换std::shared_ptrboost::shared_ptr(and boost::make_shared)

下一个错误是delete *Iter1;因为几乎所有在析构函数之外使用的代码delete都是错误的(并且所有delete在析构函数之外使用并伴随着一个关于如何避免内存泄漏的问题的代码肯定是错误的。)如果你使用 RAII 习语,你不会不需要使用delete,因为它会在正确的时间自动发生。

另外,你的课为什么叫DETAILDetail相反有什么问题?

于 2012-06-01T20:34:37.437 回答
0

我不喜欢“从不”这样的回答,所以我会回答,但会给你一些技巧来绕过释放向量而不释放内容的风险。

如果我理解得很好,你有一个 DETAIL 指针向量:

std::vector<DETAIL*> details;

因此,您需要一种方法来删除和删除所有指向某个 m_SomeVar 的指向对象:(现在让我们假设它是一个自由函数)

void free_references(int reference, std::vector<DETAIL*> & vector)
{
    std::vector<DETAIL*>::iterator it = vector.begin();

    while (it != vector.end())
    {
        if ((*it)->nRef == reference)
        {
            delete *it;
            // erase() makes the original 'it' in an unknown state which can't be used
            // erase will return a valid iterator which is, in this case, the following element
            it = vector.erase(it); 
        }
        else
        {
            ++it;
        }
    }
}

正如我在您的代码中所理解的那样,向量是一个类的成员。这很好,因为您将能够删除析构函数中的所有内容。

但是,我会std::unique_ptr在这里使用“授予”指向向量内 unique_ptr 容器的指针的所有权。并且当向量内存空闲时,std::unique_ptr智能点确保所拥有的指向对象被释放。

于 2012-06-01T20:47:44.880 回答
0

我的建议是使用 std::shared_ptr 使用擦除从向量中删除共享指针,并让它处理释放。但是,您所做的事情并没有错,但擦除不会导致向量释放它为保存指针而分配的空间。您可以使用shrik_to_fit删除分配的空间。

于 2012-06-01T18:33:17.767 回答
-2

我不知道我是否完全理解它,但你尝试过使用 ZeroMemory 宏吗?

于 2012-06-01T18:32:57.713 回答