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

问题描述 投票:0回答:2

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

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

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;
}
c++ pointers memory-leaks
2个回答
2
投票

如果deleteTest想要使用可能已经消失的对象的指针,它应该持有std::weak_ptrs。保持原始指针并在以后取消引用它是危险的(除非你可以确保对象仍然存活,a.k.a不使用原始但智能指针)。

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

如果您需要动态分配的对象,请使用智能指针(例如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中已经消失的对象和内存泄漏。使用智能指针解决了这两个问题。


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;
}
© www.soinside.com 2019 - 2024. All rights reserved.