Visual Studio 2008 发布版本上的 c++ 应用程序出现未处理异常 - 从函数返回时发生

Posted

技术标签:

【中文标题】Visual Studio 2008 发布版本上的 c++ 应用程序出现未处理异常 - 从函数返回时发生【英文标题】:Unhandled Exception with c++ app on Visual Studio 2008 release build - occurs when returning from function 【发布时间】:2010-04-09 20:49:43 【问题描述】:

我有一个用 C++ 编写的(相当大的)应用程序,直到最近它在发布版本的 Visual Studio 之外运行良好。但是,现在,每当我运行它时,它都会显示“myprog.exe 中 0x77cf205b 处的未处理异常:0xC0000005:访问冲突写入位置 0x45000200。”,并引导我到第 582 行的“crtexe.c”(“mainret = main(argc, argv, envp);") 如果我尝试调试它。请注意,如果我在 Visual Studio 之外运行我的调试可执行文件,或者如果我在 Visual Studio 中运行我的调试或发布版本,这个问题永远不会出现。只有在 Visual Studio 之外运行发布版本时才会发生这种情况。

我已经通过并在其中放入了大量的 printfs 和几个 while(1)s 以查看它何时实际崩溃,并发现访问冲突恰好发生在从函数返回值的点(我正在返回一个指向对象的指针)。我不完全明白为什么我会在它返回时遇到访问冲突,而且我返回的内容似乎并不重要,因为当我返回 0 时它仍然会发生。

它开始崩溃的时候是我添加了一个使用 ifstream 从文件中读取大量数据的函数。每次我尝试读取新文件时都会打开流,并在完成读取后关闭它。

如果我继续尝试运行它,它将在大约 20 次尝试中运行一次。如果我从笔式驱动器上运行它似乎更可靠(它似乎在前 3 或 4 次崩溃然后运行良好 - 可能是由于它的读取速度较慢)。

感谢您的帮助,如果我遗漏了什么,请告诉我。

编辑:新信息

好吧,我删除了整个函数并将其替换为:

IndexedMesh * loadObj(char * objName)


ifstream fp_in;
fp_in.open("lol.bmp", ios::in);

fp_in.clear();
fp_in.close();

IndexedMesh * mesh = new IndexedMesh();

printf("finished");


return mesh;

我还尝试了“return 0”和“return new IndexedMesh()”。在你把 ifstream 的东西放进去之前一切都很好。我确实有另外 2 个 ifstream 在不同的功能中打开(访问完全不同的文件)。会不会是这个问题?

它实际上在返回网格线上出错,(我让调试器使用单独的发布文件)。当它试图返回它时,它会将网格对象完全归零。

【问题讨论】:

我们需要一些代码。如果没有代码,这里没有人会知道您为什么会遇到访问冲突。 返回时执行“leave;ret”,清理堆栈并返回存储的地址,指示调用函数的返回位置。如果您破坏返回地址并将其设置为类似 0xFFFFFFFF "return 0;"将尝试跳转到 0xFFFFFFFF。所以你可能在某个地方破坏了堆栈。 【参考方案1】:

它开始崩溃的时候是我添加了一个使用 ifstream 从文件中读取大量数据的函数。每次我尝试读取新文件时都会打开流,并在完成读取后关闭它。

鉴于您对代码的描述仅在调试器之外的发布模式下失败,我将检查此函数是否有任何未设置的变量。像在调试器中运行发布代码一样,编译调试会设置变量(或至少以前是这样)。

【讨论】:

@Rich - 将该代码放入问题中,如果没有格式,很难弄清楚它是什么【参考方案2】:

您可能正在运行存储在堆栈深处的东西。

我敢打赌,如果您将其放在代码顶部附近:

int my_main(int argc, char * argv[], char * envp[]);

int main(int argc, char * argv[], char * envp) 
    char ** a;
    char ** e;
    a = malloc(argc+1); // note: you should test the results for NULL
    e = malloc(1+count(envp) ) ;// I'm not writing code to count it, but it's easy

    int i = 0;
    while (argv[i++]) 
       a[i] = strdup(argv[i]);
    
    a[i] = argv[i]; // argv[i] is NULL and already in a register

    // do the same thing for envp

    return my_main(argc, a, e);

#define main my_main

那么无论是什么破坏了你的堆栈,最终都会破坏这个重复的环境。它不是garenteed,也无法解决您的问题,但并不难。

【讨论】:

【参考方案3】:

非常感谢您的帮助,我还没有完全解决这个问题,但我设法避免了它。基本上,如果我什至提到了一个 ifsteam(在那个函数和那个函数中),程序就会崩溃。

实际上,我将函数更改为简单地声明一个 ifstream 然后返回 0。我通过将 ifstream 声明为指针并对其进行更新来“修复”它。如果我删除了指针,它又崩溃了,所以我不得不将它设置为 0 (leeeeak)。

如果有人能告诉我为什么会发生这种情况,那就太好了。虽然我很高兴它现在可以工作,但我更想知道为什么..

【讨论】:

神奇地消失的问题会神奇地回来,而且在最糟糕的时刻。对于堆栈覆盖问题尤其如此。在找出或解释最初的问题究竟是什么之前,不要高兴。

以上是关于Visual Studio 2008 发布版本上的 c++ 应用程序出现未处理异常 - 从函数返回时发生的主要内容,如果未能解决你的问题,请参考以下文章

持续集成:Visual Studio 2008 上的非托管 C++

如何部署和注册支持多个版本的 Visual Studio(2005、2008、2010)的 VSPackage?

Visual Studio 2008 + Windows Vista 上的嵌入式 Web 服务器

从 Visual Studio 2005 移植到 2008 或更高版本

使用 Visual Studio 2008 和 SVN 在 C++ 中进行自动版本控制

有没有Visual Studio 2008 运行时版本的总结?