当我们“必须”将指针循环传递给某些函数时,如何防止内存泄漏?

时间:2019-04-04 17:47:14

标签: c++ pointers memory-leaks

我遇到一种情况,我必须以指针(指向类对象)作为参数来循环调用一个函数。问题是,我无法修改该函数的签名,并且每次循环迭代都必须初始化指针。这将导致内存泄漏,因为我无法在循环内删除指针(将其传递给函数后)。在这种情况下,有什么方法可以防止内存泄漏吗?

我想用一个简单的例子来解释:

class testDelete
{
    public:
        void setValue(int* val) {vec.push_back(val);};
        void getValue();
    private:
        vector <int*> vec;
};
void testDelete::getValue()
{
    for (int i=0;i<vec.size();i++)
    {
        cout << "vec[" << i << "] = " << *vec[i]<<"\n";
    }
}

int main()
{
    testDelete tD;
    int* value = NULL;
    for (int i=0;i<10;i++)
    {
        value=new int(i+1);
/*I am not allowed to change this function's signature, and hence I am forced to pass pointer to it*/
        tD.setValue(value); 
/*I cannot do delete here otherwise the getValue function will show garbage value*/ 
        //delete value;
    }

    tD.getValue();
    return 0;
}

2 个答案:

答案 0 :(得分:2)

如果deleteTest要使用可能已消失的对象的指针,则应保留std::weak_ptr个。 坚持使用原始指针并在以后对其取消引用是危险的(除非您可以确保该对象仍然存在,否则请不要使用原始但智能的指针)。

  

[...]我无法修改该函数以及每个函数的签名   循环的迭代,我必须初始化指针。在这种情况下,有什么方法可以防止内存泄漏吗?

如果需要动态分配的对象,请使用智能指针(例如std::smart_ptr以获得共享所有权)。如果您不需要动态分配它们,则不需要。

为了便于说明,假设您无法修改deleteTest,则对于整数,没有理由动态分配任何内容

int main()
{
    std::array<int,10> x;
    testDelete tD;        
    for (int i=0;i<10;i++)
    {
        x[i] = i+1;
        tD.setValue(&x[i]); 
    }    
    tD.getValue();
    return 0;
}

带着些许麻烦,实际上是deleteTest,需要加以修复以避免造成麻烦。

TL; DR

在您的示例中,您实际上有两个问题。 deleteTest可能会尝试访问main中已经消失的对象和内存泄漏。使用智能指针可以同时解决这两个问题。

答案 1 :(得分:2)

将整数存储在容器中

int main()
{
    std::vector<int> values(10);

    testDelete tD;
    for (int i=0;i<10;i++)
    {
        values[i] = i + 1;
        tD.setValue(&values[i]);
    }

    tD.getValue();
    return 0;
}