开发者

C++, Can't use an array or vectors, how do I use a pointer to get through this mess?

I need help with pointers and memory management.

I need to store different objects, all derived from the same base class, and have been using an array to do this but it is causing a segmentation fault when the array is populated with different objects.

My program works fine when the array is full of objects of the same derived type. When the array is populated with different objects it works as it is supposed to through the object stored at the firs开发者_开发技巧t position but then when it switches to output the second object it gives me the segmentation fault. I know that this is a memory access issue but I am unclear how I'm supposed to manage a variable amount of objects dependent on user input.

thx, nmr


Make sure the pointers you're pushing on the stack are dynamically allocated. The following will fail:

std::vector<Base*> objects;

void make_one(void)
{
    Derived d;

    objects.push_back(&d);
}

Because when the function ends, the class pointed to by &d will be deallocated. This is alleviated by dynamically allocating the objects:

std::vector<Base*> objects;

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

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

Just remember to go through the vector when you're done, and call delete on them:

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

}

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

If you can use boost, there is a pointer container library that will do this for you. Note, you cannot use auto_ptr and try to let it do it for you; auto_ptr's don't play well with containers.

Also, make sure your base classes have virtual destructors:

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

If they are not, calling delete on a base class will run the base constructor only, leaking any resources the derived class might of had. By making it virtual, the compiler can jump to the correct destructor.


I won't post a complete solution because you have identified the question as homework, but I hope I can help you out with the problem a little bit:

Arrays are designed to hold many objects of the same size. The problem with storing different objects in the array (even if they are derived from the same base class) is that the objects are likely to have different sizes.

You're definitely on the right track by thinking about pointers.

edit (in response to comments):

You would be looking at something like this:

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

A pitfall of this approach would be that there is no built-in deletion of the objects in the array. You would have to loop through and call delete manually:

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


It looks very similar to the problem mentioned here: Is array of derived same as array of base? . Are you creating a array of derived objects and trying to access as if it is an array of base?

You can use array of base pointers like this, but note that it is better to use std::vector<Base*> instead of raw arrays:

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;
};
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜