C++ 迭代器/向量在发布版本中不起作用

Posted

技术标签:

【中文标题】C++ 迭代器/向量在发布版本中不起作用【英文标题】:C++ iterator/vector not working in release build 【发布时间】:2014-02-05 12:27:10 【问题描述】:

我正在使用向量/迭代器在不同的类中执行方法,这在调试和我们使用相同方法的其他地方工作得很好。但是由于某种原因,当我在发行版中运行此代码时,出现以下错误:

FOO.exe 中 0x011d2928 处未处理的异常:0xC0000005:访问冲突。

std::vector<AbstractClass*> vectorClasses;
vectorClasses.push_back(&SomeClass1());
vectorClasses.push_back(&SomeClass2());
vectorClasses.push_back(&SomeClass3());

CString result;     
std::vector<AbstractClass*>::iterator it

for(it = vectorClasses.begin() ; it != vectorClasses.end() ; it++)

   result = (*it)->DoSomething(s1, s2);
   if(!IsBlank(result))
   
       //Do something
       break;
   

为什么会这样?错误与使用向量/迭代器有关吗? 让我想到它与迭代器有关的是,当我调试它(​​发布)时,Visual Studio 完全跳过了我声明我的迭代器的那一行(这在调试中不会发生)。

当我调试发布版本时,尝试执行该行时出现错误:

result = (*it)->DoSomething(s1, s2);

【问题讨论】:

s2 在哪里定义? SomeClass1 的构造函数发生了什么?向我们展示代码。 vectorClasses.push_back(&amp;SomeClass1());添加临时地址... 错过包含它们应该只是两个不同的字符串。 【参考方案1】:

您不能保留临时对象的指针。内存会被重用,所以你有无效的内存访问

std::vector<AbstractClass*> vectorClasses;
vectorClasses.push_back(&SomeClass1()); // ill formed, SomeClass1() is create on the stack and destroy after push_back call is done, referencing the pointer after that is invalid as it will not be a SomeClass1 anymore.

因为你需要多态,你应该这样做,智能指针必须优先于裸指针。

std::vector<std::unique_ptr<AbstractClass>> vectorClasses;
vectorClasses.push_back( std::make_unique<SomeClass1>() );
vectorClasses.push_back( std::make_unique<SomeClass2>() );
vectorClasses.push_back( std::unique_ptr<SomeClass3>( new SomeClass3 ) ); // if make_unique not available

【讨论】:

你在说什么狐狸? 查看编辑,不使用new不是在堆上创建的,所以在栈上是临时的 @WeaselFox:如果类在内部动态分配内存,那很好,但我们仍然需要空间用于指针或类按值保存的任何内容。 std::vector 无效,不能创建抽象类实例,它可以是 std::vector 或 std::vector @TNA,因为OP使用多态性,使用vector&lt;AbstractClass&gt;会切片存储在向量中的对象和损失信息,而不是你想要的。【参考方案2】:

您正在添加一个临时对象的地址

vectorClasses.push_back(&SomeClass1());

问题是该对象在语句之后无效。

【讨论】:

【参考方案3】:

而不是这个:

vectorClasses.push_back(&SomeClass1());

你需要这个:

vectorClasses.push_back(new SomeClass1());

在第一种(错误的)情况下,您正在存储一个临时对象的地址,该对象很快就会被销毁,因此无法使用。在第二种(固定)情况下,我们存储了一个堆分配的对象,该对象将一直存在到您 delete 它(您应该在程序结束时执行此操作,但如果您忘记了操作系统将清理分配的记忆)。

【讨论】:

【参考方案4】:

以下应该可以解决您的问题, 它不再保留对已删除临时文件的引用:

SomeClass1 someClass1;
SomeClass2 someClass2;
SomeClass3 someClass3;

std::vector<AbstractClass*> vectorClasses;
vectorClasses.push_back(&someClass1);
vectorClasses.push_back(&someClass2);
vectorClasses.push_back(&someClass3);

假设您不删除 vectorClasses 内容。

【讨论】:

以上是关于C++ 迭代器/向量在发布版本中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Laravel:array_push 在 collection->each() 迭代器中不起作用

预处理器定义在 VS2019 C++ 中不起作用

C++:使用迭代器替换部分字符串不起作用

vector.push_back() 方法调用在 C++ 中不起作用

我的迭代器实现不起作用,它有啥问题?

为 glm 翻译添加统一向量在 OpenGL 中不起作用