c++ - 使用 o2 标志编译会使程序出现访问冲突

标签 c++ visual-studio-2010 optimization assembly access-violation

我知道这可能是一生一次的问题,但我一直坚持下去,我想不出任何可能的问题,我已经用 C++ 编写了一个代码(大约 500 行,单独的类和文件)使用 visual studio,虽然我在没有优化标志(/od)的情况下编译它,但它工作正常,但是当我尝试使用发布配置(/o2 优化标志)编译它时,程序会出现访问冲突和崩溃。经过一些调试后,我发现有一个 this 值在其中一个成员函数内发生变化,但我看不到调用堆栈中指针的任何直接使用是指针变化,任何人都可以给出任何建议只有在启用优化时才会发生这种情况?

不知道这是否对您有帮助,但是当我使用优化进行编译时,我可以看到在我的第一个函数调用结束时添加了一个汇编指令 pop ebp don不知道这个是做什么的,但不管它是什么,这就是这个指针改变的地方。

我在尝试使用反汇编程序进行调试时发现的一些新东西,导致问题的函数中有 13 个 push 指令和只有 10 个 pop 指令(问题是由 ret 指令之前的最后一个 pop 引起的)是否可以? (我也在计算被调用的函数中的所有 push、pop 指令。)

最佳答案

您看到优化和未优化行为不同的原因是您的代码(无意中)依赖于未定义的行为。如果编译器以一种方式布局数据,它恰好可以工作,如果编译器以不同的方式布局数据,它就会中断。

换句话说,你有一个错误。

它可能存在于您已经测试过的代码中,也可能存在于您使用该代码的方式中。无论如何,正如@Nim 在评论中所说,请检查分配和释放内存的位置。检查您的类(class)是否遵循三原则。确认您在某处没有缓冲区溢出。也许,也可以尝试使用不同的编译器对其进行编译。使用静态分析工具(MSVC 有/analyze,Clang 有 --analyze。在 Linux 上,Valgrind 可能是一个不错的选择)。

但不要认为这是编译器错误。这些确实会发生,当然,但它们通常不是此类错误的根源。几乎在每种情况下,它都是开发人员自己的代码中的潜在错误。仅仅因为它不是每次都触发,每个编译器标志并不意味着它不存在,或者是编译器的错。

关于c++ - 使用 o2 标志编译会使程序出现访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6145134/

相关文章:

c++ - 如何通过扩展以下类型特征来删除 decltype(& MyClass::func) 部分?

尝试使用 ProGuard 优化 Java+Scala 时出现 java.lang.StackOverflowError

SQL如何更新同一个表中组的列的SUM

c++ - 如何重新导出 CLR c++ 静态库

winforms - 如何在 Visual Studio 中创建 Windows 控件库项目?

c# - Visual Studio 单元测试安全异常

Python,组合,排列无重复

c++ - VSCode 上的 PlatformIO 未编译 : collect2. exe:错误:ld 返回 1 退出状态

c++ - 使用函数定义作为友元声明时,clang 和 gcc 之间的行为差​​异

c# - 使用 SWIG 更改生成的 CS 函数中的返回类型