C ++,不能使用数组或向量,如何使用指针来解决这个问题呢?

时间:2009-11-19 05:19:48

标签: c++ arrays memory-management pointers

我需要有关指针和内存管理的帮助。

我需要存储不同的对象,这些对象都是从同一个基类派生的,并且一直在使用数组来执行此操作,但是当使用不同的对象填充数组时,它会导致分段错误。

当数组中充满了相同派生类型的对象时,我的程序工作正常。当数组填充不同的对象时,它应该通过存储在第一个位置的对象,但是当它切换到输出第二个对象时,它会给我分段错误。我知道这是一个内存访问问题,但我不清楚我应该如何管理依赖于用户输入的可变数量的对象。

THX, NMR

3 个答案:

答案 0 :(得分:5)

确保您在堆栈上推送的指针是动态分配的。以下内容将失败:

std::vector<Base*> objects;

void make_one(void)
{
    Derived d;

    objects.push_back(&d);
}

因为当函数结束时,&d指向的类将被释放。通过动态分配对象可以缓解这种情况:

std::vector<Base*> objects;

void make_one(void)
{
    Derived *d = new Derived;

    objects.push_back(d); // a-ok
}

请记住在完成后浏览向量,并在其上调用delete

struct deleter
{
    template <typename T>    
    void operator()(T* pObject) const
    {
        delete pObject;
    }

}

std::for_each(objects.begin(), objects.end(), deleter());

如果您可以使用提升,则会有pointer container library为您执行此操作。请注意,您无法使用auto_ptr并尝试让它为您执行此操作; auto_ptr的容器效果不佳。

另外,请确保您的基类具有虚拟析构函数:

struct base
{
    virtual ~base(void) {} // important!
}

如果不是,则在基类上调用delete将仅运行基础构造函数,泄漏派生类可能具有的任何资源。通过使其成为虚拟,编译器可以跳转到正确的析构函数。

答案 1 :(得分:1)

我不会发布完整的解决方案,因为您已将问题确定为家庭作业,但我希望我能帮助您解决问题:

数组用于容纳许多大小相同的 。在数组中存储不同对象的问题(即使它们是从相同的基类派生的)是对象可能具有不同的大小。

通过思考指针,你肯定是在正确的轨道上。

修改(以回应评论):

你会看到这样的事情:

BaseClass * array[size];
array[0] = new DerivedClass(...);
array[1] = new OtherDerivedClass(...);
...

这种方法的一个缺陷是没有内置的数组中对象的删除。您必须循环并手动调用delete

for (int index = 0; index < size; index++) { delete array[index]; }

答案 2 :(得分:0)

它看起来非常类似于此处提到的问题:Is array of derived same as array of base?。您是否正在创建派生对象数组并尝试访问它,就像它是一个基数组一样?

您可以使用这样的基本指针数组,但请注意,最好使用std::vector<Base*>而不是原始数组:

class Base
{
public:
    virtual ~Base(){}
    virtual void f() {std::cout<<"Base::f()\n";}
};


class Derived1: public Base
{
public:
    ~Derived1(){}
    void f(){std::cout<<"Derived1::f()\n";}
};

class Derived2: public Base
{
public:
    ~Derived2(){}
    void f(){std::cout<<"Derived2::f()\n";}
};


void print(Base** p, int count)
{
    for(int i = 0; i < count; ++i)
    {
        (*p)->f();
        ++p;
    }
}

int main()
{
    Base b;
    Derived1 d1;
    Derived2 d2;

    Base* arr[3];
    arr[0] = &b;
    arr[1] = &d1;
    arr[2] = &d2;

    print(arr, 3);


    return 0;
};