C ++ Vector Push_back产生奇怪的副作用

时间:2014-07-17 20:56:04

标签: c++ pointers vector reference

当我使用STL向量来存储类对象时,我发现了一个非常奇怪的副作用,其中push_back方法修改了现有数据!

基本上我有一个包含多个字段的类,如下所示:

class MyClass {
    MyClass(std::string s, int i) {
        StringValue = s;
        IntValue = i;
    }

    std::string StringValue;
    int IntValue;
}

我有一个包含 POINTERS 到MyClass对象的向量..然后我基本上推回对对象的引用:

std::vector<MyClass*> MyVector;
MyClass c1("CLASS 1", 1);
MyClass c2("CLASS 2", 2);

MyVector.push_back(&c1);
// Result:
// *MyVector[0]    ==>    ("Class 1", 1)



MyVector.push_back(&c2);
// Result:
// *MyVector[0]    ==>    ("Class 2", 2)   ??why 2??
// *MyVector[1]    ==>    ("Class 2", 2)

你看到我得到的奇怪结果吗?我在每个push_back语句后都设置了断点,,,这个奇怪的事情发生了。

第一个push_back语句运行正常。但是第二个push_back语句 MODIFIED 第一个元素的内容,这对我来说没有意义..

我假设它与我存储引用而不是向量中的实际对象有关...但我无法弄清楚出了什么问题。

我该如何处理这个问题?任何见解?

由于


更新:

(简化代码)

MyClass c1("CLASS 1", 1);
MyClass c2("CLASS 2", 2);

MyClass temp;
while (int i=0; i<2; i++) {
    temp = c1;
    MyVector.push_back(temp);
}

你们是对的,我得到的是我在这里做错了..实际的对象在每个循环中被破坏..在保持当前结构的同时解决这个问题的最佳方法是什么?我很难解释,但我想保留这个结构(将临时缓冲区保留在循环之外)..这可能吗?

1 个答案:

答案 0 :(得分:4)

我会走出困境并利用我的精神力量来获得真实的代码,而不是问题中的简化代码。你的真实代码看起来像......鼓声......

class MyClass {
    // ...
};

void addInstance(std::vector<MyClass*>& MyVector, int i) {
    MyClass c("", i);
    MyVector.push_back(&c);
}

int main() {
    addInstance(MyVector, 1);
    addInstance(MyVector, 2);
    // ...
 }

这是一个展示问题的工作示例,确实输出了&#34; 2,2&#34; (虽然因为您正在调用未定义的行为而无法保证):

http://ideone.com/PxiUx9

编辑:我的通灵力量表示&#34;自动变量功能&#34;什么时候(现在我们有更新的问题)它真的是#34;在循环中自动变量&#34;。没有太大的错误。 : - )

您将自动变量的地址存储在其生命周期之外,这是不允许的。地址在每次调用时被重复使用,因此存储的每个指针都是相同的,并且碰巧指向最后用于存储最近创建的MyClass实例的内存(尽管不能保证)。

您需要(最好)存储这些自动变量的副本而不是指向它们的指针,或者(不太优选)使用new创建它们,然后使用delete删除它们。

要存储副本,您需要使用std::vector<MyClass>。以下是您如何做到这一点的一个示例:http://ideone.com/4rIijM请注意,一旦您的类变得更复杂,您可能需要定义一个复制构造函数,析构函数和赋值运算符 - 查找&#34;规则3&#34 ;.如果你正在使用C ++ 11,那么也要查看&#34;规则的五个&#34;。