Question

I'm implementing a Barnes-Hut simulation program, and have this short snippet of code:

BhTree *BhTree::make() {
    return new BhTree();
}

The rest of the code (substantial) then works great. The created nodes are never deleted during the program lifetime. Using this fact, I wanted to optimize the allocation by using this:

vector<BhTree> mSpace;
BhTree *BhTree::make() {
    mSpace.push_back(BhTree());
    return &mSpace[mSpace.size()-1];
}

This leads to a dreaded segmentation fault in an unrelated section of the code. Interestingly, in a recursive function, where this has suddenly been transformed into 0xfeeefeee, the Microsoft code for heap-freed memory.

Can anyone see off-hand what the problem might be? The vector mSpace is never accessed elsewhere.

Was it helpful?

Solution

As the std::vector grows it will reallocate memory for its contents and invalidate all the previous pointers you handed out.

OTHER TIPS

You are returning a pointer to an object managed by the vector:

&mSpace[mSpace.size()-1];

The address will become invalid as soon as the vector expands it's internal buffer, and copies the objects to a new location.

You have 3 options:

  • Change all your code to pass your objects by value/reference instead of pointers
  • Make the vector store std::shared_ptr<Bhtree> instead (if your compiler supports C++ 11).
  • Make the vector store Bhtree* and make sure to delete each element

The second variant would look like this:

std::vector<std::shared_ptr<Bhtree>> mSpace;

BhTree *BhTree::make() {
    mSpace.push_back(std::make_shared<BhTree>());
    return mSpace.back().get();
}

mSpace.push_back() can resize the vector internal array when it determines that it is out of space. When this happens the internal array of the vector becomes invalid and the old pointers to the vector elements are also invalid.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top