在堆上释放内存后 - 向量仍然保持(悬空)向量中的指针。如何完全删除vector-elements?
vector<Obstacle*> obstacles;
vector<Action*> actions;
void Game::free(GameFactory *gFact) {
obstacles = gFact->getObstacles();
actions = gFact->getActions();
destroyVectorElements(obstacles);
destroyVectorElements(actions);
}
template<typename T>
void destroyVectorElements(vector<T> &vec) {
typename vector<T>::iterator start=vec.begin(), stop=vec.end(), it;
for(it=start; it!=stop; ++it) {
delete (*it);
}
}
重新分配有效,但是矢量列表仍然存在悬挂指针。
答案 0 :(得分:3)
删除迭代后调用vec.clear()。
template<typename T>
void destroyVectorElements(vector<T> &vec) {
typename vector<T>::iterator start=vec.begin(), stop=vec.end(), it;
for(it=start; it!=stop; ++it) {
delete (*it);
}
vec.clear();
}
答案 1 :(得分:1)
如果您想在迭代时执行此操作(如果需要delete
子范围,则非常有用),请在erase
指针后调用delete
。请注意,您还需要重新计算vec.end()
,因为迭代器将失效:
template<typename T>
void destroyVectorElements(vector<T> &vec) {
typename vector<T>::iterator start=vec.begin(), it;
for(it=start; it!=vec.end(); ++it) {
delete (*it);
it = vec.erase(it);
}
}
或者,您可以在执行迭代后调用clear
。
或者,您可以(并且应该)使用std::unique_ptr
(或std::shared_ptr
如果您拥有共享所有权)来回避整个问题。
答案 2 :(得分:0)
您必须了解向量中实际保存的元素与向量中的元素所指向的元素之间的区别。在您的情况下,向量元素是指向动态分配对象的指针。在这些上调用delete将释放堆内存,但vector元素本身保持不变。
在向量上调用 vec.clear()
以清除其内容。