c ++指针管理与局部变量

时间:2010-10-18 15:50:18

标签: c++ pointers memory-management

我有一个方法可以创建一些Foo并将其添加到Foos矢量中。 Foos负责在销毁期间删除他们的酒吧。 Foo构造函数采用Bars的指针及其大小。当函数返回时,本地Foo被删除并销毁其Bars,但是我得到了一个有效的Foo对象。

我应该如何更正确地处理这个问题?我应该以其他方式管理酒吧吗?我应该让构造函数复制数组吗?我可能会有成千上万的酒吧。

没有尝试编译它,这只是一个正在发生的事情的例子。

class Bar
{
    public:
        Bar(){}
        ~Bar(){}

        int a;
        int b;
        int c;
};

class Foo
{
    private:
        Bar * myBars;
        int size;

    public:
        Foo(Bar * myBars, int size)
        {
            this->myBars = myBars;
            this->size = size;
        }

        Bar * getBars()
        {
            return myBars;
        }

        int getSize()
        {
            return size;
        }

        ~Foo()
        {
            if(myBars != NULL)
            {
                if(size == 1)
                {
                    delete myBars;
                }
                else if(size > 1)
                {
                    delete [] myBars;
                }
            }
        }
};

void doIt(std::vector<Foo> & foos)
{
    Bar * myBars = new Bar[4];
    //Pretend we initialize the Bars...
    Foo foo(myBars);
    foos.push_back(foo);

    //local foo gets deleted
}

int main()
{
    std::vector<Foo> foos;
    doIt(foos);

    Bar * myBars = foos[0].getBars();
    int size = foos[0].getSize();

    //Do something with myBars

    return 0;
}

3 个答案:

答案 0 :(得分:1)

为什么不将std::vector用于Bar s:

class Foo
{
    private:
        vector<Bar> myBars;

    public:
        Foo(const vector<Bar>& bars) : myBars(bars) {}

        vector<Bar>& getBars()
        {
            return myBars;
        }

        int getSize()
        {
            return myBars.size();
        }
};

答案 1 :(得分:0)

与Bars类似,您也可以在堆上创建Foo对象,以避免在doIt functon中被破坏。如果动态分配Foo对象,则在返回doIt()函数时不会销毁它。

您可以像下面一样清理所有Foo和Bar对象(工作代码)

#include <vector>
using namespace std;
class Bar 
{ 
    public: 
        Bar(){} 
        ~Bar(){} 

        int a; 
        int b; 
        int c; 
}; 

class Foo 
{ 
    private: 
        Bar * myBars; 
        int size; 

    public: 
        Foo(Bar * myBars, int size) 
        { 
            this->myBars = myBars; 
            this->size = size; 
        } 

        Bar * getBars() 
        { 
            return myBars; 
        } 

        int getSize() 
        { 
            return size; 
        } 

        ~Foo() 
        { 
            if(myBars != NULL) 
            { 
                if(size == 1) 
                { 
                    delete myBars; 
                } 
                else if(size > 1) 
                { 
                    delete [] myBars; 
                } 
            } 
        } 
}; 

void doIt(std::vector<Foo *> & foos) 
{ 
    Bar * myBars = new Bar[4]; 
    //Pretend we initialize the Bars... 
    Foo *pFoo = new Foo(myBars, 4); 
    foos.push_back(pFoo); 
} 

int main() 
{ 
    std::vector<Foo *> foos; 
    doIt(foos); 

    Bar * myBars = foos[0]->getBars(); 
    int size = foos[0]->getSize(); 

    for(int i = 0;i < foos.size(); i++)
    {
        delete foos[i];
    }
    foos.clear();

    return 0; 
} 

答案 2 :(得分:0)

您没有显示复制构造函数,也没有适当的默认复制构造函数。 您也没有stl容器经常需要的默认(无参数)构造函数。

当你将Foo推入向量时,它会创建一个新的Foo作为副本。

目前您可能会两次删除条形指针。

在使用非POD类型时应避免使用本机数组 - Bar[4]将不会在Bar上为每个对象运行构造函数。喜欢使用Vector