释放指针向量的两种不同方法——为什么一种方法不起作用?
Two different ways of deallocating vector of pointers - why doesn't one work?
我有一个指向结构的指针向量。第一种释放内存的方法工作正常,但第二种方法在执行后会出现分段错误(核心转储)。为什么呢?两者对我来说都是正确的。使用g++编译。
struct milkNode {
int unitCost;
int unitsAvail;
};
int main() {
//previous code
for (int i = 0; i < M; ++i) {
milkNode *cur = new milkNode;
cur->unitCost = cost;
cur->unitsAvail = avail;
allNodes.push_back(cur);
}
//Method 1, works fine
vector<milkNode*>::iterator iter;
for (iter = allNodes.begin(); iter != allNodes.end(); ++iter) {
delete *iter;
}
allNodes.clear();
//Method 2, segmentation fault after execution. Compiles without errors.
//Segmentation fault occurs just before the last "after" is printed
/*
vector<milkNode*>::iterator iter;
for (iter = allNodes.begin(); iter != allNodes.end(); ++iter) {
milkNode *delThis = allNodes.back();
allNodes.pop_back();
cout << "before" << endl;
delete delThis; //Attempted to put this statement before pop_back, still seg fault.
cout << "after" << endl;
}*/
return 0;
}
已经浏览了一些像这样的 Whosebug 帖子:Deleting vector of pointers,但它们似乎没有回答我的问题。
在某些时候 iter
将引用列表中的最后一个元素,并在循环中弹出该元素并将其删除。这会使迭代器无效,然后您会出现未定义的行为 - 您随后对 end()
和增量的测试无法依赖。
因为您实际上并不需要迭代器,所以替换它会容易得多
for (iter = allNodes.begin(); iter != allNodes.end(); ++iter) {
和
while (!allNodes.empty()) {
这样可以避免问题。
第二个应该是:
while (!allNodes.empty()) {
milkNode *delThis = allNodes.back();
allNodes.pop_back();
delete delThis;
}
让我们看一下循环的 "last" 次迭代:
iter
等于 allNodes.end() - 1
。然后你 pop_back()
在 allNodes
,现在 iter
等于 allNodes.end()
。最后我们回到循环头,增加 iter
现在是 allNodes.end() + 1
!
这就是你的循环失败的地方。
我有一个指向结构的指针向量。第一种释放内存的方法工作正常,但第二种方法在执行后会出现分段错误(核心转储)。为什么呢?两者对我来说都是正确的。使用g++编译。
struct milkNode {
int unitCost;
int unitsAvail;
};
int main() {
//previous code
for (int i = 0; i < M; ++i) {
milkNode *cur = new milkNode;
cur->unitCost = cost;
cur->unitsAvail = avail;
allNodes.push_back(cur);
}
//Method 1, works fine
vector<milkNode*>::iterator iter;
for (iter = allNodes.begin(); iter != allNodes.end(); ++iter) {
delete *iter;
}
allNodes.clear();
//Method 2, segmentation fault after execution. Compiles without errors.
//Segmentation fault occurs just before the last "after" is printed
/*
vector<milkNode*>::iterator iter;
for (iter = allNodes.begin(); iter != allNodes.end(); ++iter) {
milkNode *delThis = allNodes.back();
allNodes.pop_back();
cout << "before" << endl;
delete delThis; //Attempted to put this statement before pop_back, still seg fault.
cout << "after" << endl;
}*/
return 0;
}
已经浏览了一些像这样的 Whosebug 帖子:Deleting vector of pointers,但它们似乎没有回答我的问题。
在某些时候 iter
将引用列表中的最后一个元素,并在循环中弹出该元素并将其删除。这会使迭代器无效,然后您会出现未定义的行为 - 您随后对 end()
和增量的测试无法依赖。
因为您实际上并不需要迭代器,所以替换它会容易得多
for (iter = allNodes.begin(); iter != allNodes.end(); ++iter) {
和
while (!allNodes.empty()) {
这样可以避免问题。
第二个应该是:
while (!allNodes.empty()) {
milkNode *delThis = allNodes.back();
allNodes.pop_back();
delete delThis;
}
让我们看一下循环的 "last" 次迭代:
iter
等于 allNodes.end() - 1
。然后你 pop_back()
在 allNodes
,现在 iter
等于 allNodes.end()
。最后我们回到循环头,增加 iter
现在是 allNodes.end() + 1
!
这就是你的循环失败的地方。