我认为我有一些误解如何通过值与参考值来移动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