我認爲我有一些誤解如何通過值與參考值來移動STL容器 對象。具體地講,我不明白爲什麼 下面的程序崩潰:STL容器對象按值與參考
#include <vector>
#include <set>
#include <cstdio>
class Value {
public:
int x, y;
Value(int a, int b) { x = a; y = b; }
};
class Test {
public:
Test(int x, int y) { values.insert(new Value(x, y)); }
void add(int x, int y) { values.insert(new Value(x, y)); }
std::set<Value *> getValues() { return values; }
private:
std::set<Value *> values;
};
int main() {
std::vector<Test> Ts;
for (unsigned i = 0; i < 5; i++) {
Test t(0, 0);
t.add(i, 0);
Ts.push_back(t);
}
for (unsigned i = 0; i < 5; i++) {
for (std::set<Value *>::iterator it = Ts.at(i).getValues().begin(), ite = Ts.at(i).getValues().end(); it != ite; ++it) {
Value *v = *it;
printf("(%d, %d) ", v->x, v->y);
}
printf("\n");
}
return 0;
}
在第二個for循環此程序段錯誤(試圖在Ts
矢量打印 值)。但是,如果將初始循環更改爲:
for (unsigned i = 0; i < 5; i++) {
Ts.push_back(Test(0, 0));
}
然後程序執行正常。此外,如果你拿第一 程序(崩潰)和打印循環更改爲:
for (unsigned i = 0; i < 5; i++) {
std::set<Value *> values = Ts.at(i).getValues();
for (std::set<Value *>::iterator it = values.begin(), ite = values.end(); it != ite; ++it) {
Value *v = *it;
printf("(%d, %d) ", v->x, v->y);
}
printf("\n");
}
然後該程序不會崩潰。
我想了解是什麼導致這些崩潰,程序之間的差異是什麼。
std::set<Value *> getValues() { return values; }
該成員函數返回的指針集的副本:
您是否知道您的程序正在泄漏內存?在'Test'類中使用'new'完全沒有理由。 – pmr 2014-09-24 16:04:53
@pmr是的。這是我的大型程序的簡化測試用例版本,它稍後可以正確釋放這些值。 – 2014-09-24 16:06:24
除了你正在泄漏內存的部分外,你還在for循環中設置了'values'的多個副本,因爲'getValues()'返回一個副本。這可能是迭代器在內存中處於不利位置的原因,導致分段錯誤。 – 2014-09-24 16:06:41