0

I have a problem with an array of pointers to objects :(..

I need to generate a dynamic vector of object and then return it in order to manipulate it in another class. In the code below there is Event class that is abstract and CarArrival that inherits from it and can be instantiated.

Inside the class that generate and fill the array I have this function:

Event** EventGenerator::getEvents() {

Event* cars[EVENTS];

for (int i=0; i<EVENTS; i++) {
    cars[i] = new CarArrival(generator->getNextNumber(8,(float)sqrt(0.4)));
}

sort(cars, cars+(EVENTS), Event::cmp);

return cars;

}

I invoke this function in onther class in this way:


Event** cars = generator->getEvents();

for(int i=0; i<EVENTS; i++) {
    cout << i <<":" << (*cars)[i]->getScheduleTime() << endl;
}

after the print of the first element i get "Segmentation Fault".

I have read some things online and I understand that I mistake since (*cars) evaluates to a pointer to the first element of the array, in fact I can print the first element and not the other, but I cannot figure out how to access every element of the array in the second class.

How can I face this?

Thanks to all,

Alberto

2
  • "I need to generate a dinamic vector of object"... Hmm, If only there was a std::vector... Commented Dec 6, 2011 at 11:21
  • Only use pointers if you really have to. Use the STL whenver possible, it's well tested and you save yourself a lot of trouble. Commented Dec 6, 2011 at 11:23

4 Answers 4

5

I'd suggest that you use a std::vector<Event*> instead. You'll save a lot of pain this way. It takes care of all the nasty memory management in the background, and you can easily push any number of items into it. The best part in your case is, that you can simply return a vector which is not safe with a normal array.

Also your Event* cars[EVENTS]; is declared locally in you function. After you have finished it, it ceases to exist, which might cause your Segfault. You'd have to dynamically allocate the array with new, but still, try it with std::vector, see the documentation here.

EDIT: Sample Usage:

std::vector<Event*> EventGenerator::getEvents() {
    std::vector<Event*> cars;
    for (int i=0; i<EVENTS; i++) {
        cars.push_back(new CarArrival(generator->getNextNumber(8,(float)sqrt(0.4))));
    }

    sort(cars.begin(), cars.end(), Event::cmp);

    return cars;
}

std::vector<Event*> cars = generator->getEvents();

for(int i=0; i<cars.size(); i++) {
    cout << i <<":" << (*cars)[i]->getScheduleTime() << endl;
}
Sign up to request clarification or add additional context in comments.

Comments

3

I believe the cleanest way to handle a dynamic vector of pointers to dynamically allocated objects is to use a boost::ptr_vector. It handles everything you need, including allocation of the space to store the pointers, and deletion of those pointers afterwards.

Comments

2

Wouldn't be better to return vector<Event*> or vector<shared_ptr<Event>> instead of raw pointers? This way you would gain:

  1. Automation of the memory management
  2. Dynamic array with built-in length instead of fixed one

Comments

2

As mentionned by Constantinuis, you are returning the value of a pointer to a memory location that is only valid in the scope of the getEvents() function (it's allocated on the stack). You're bound to get a segfault next time.

You probably want to allocate the memory for this array in the heap (using 'new' if my C++'s isn't too rusty), and then you'll have to deal with freeing the memory later.

http://www.linuxtopia.org/online_books/programming_books/thinking_in_c++/Chapter13.html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.