As the std::vector
grows it will reallocate memory for its contents and invalidate all the previous pointers you handed out.
0xfeeefeee segmentation fault, but simple allocation change?
-
18-07-2023 - |
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.
Solution
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 todelete
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.