当我运行从Visual C ++我在Release模式的应用,我发现了以下情况例外。
未处理的异常:System.AccessViolationException:尝试读取或写入受保护的内存。 这通常是一个指示其他内存已损坏。 在在.LanguageSupport._UninitializeDefaultDomain(无效* cookie中)在.LanguageSupport.UninitializeDefaultDomain()_cexit()在.LanguageSupport.DomainUnload(对象源,伊芙ntArgs参数)在.ModuleUninitializer.SingletonDomainUnload(Objec吨源,EventArgs的参数)
这并不在调试模式下发生的。 起初,我看到我家的电脑上此异常,但不工作的计算机。 当我继续我的工作电脑上进行开发,最后我碰到它。
另外,我发现,当我添加了三个常量的std :: string变量的异常被抛出。 如果我然后取出然后一切顺利。
另一条信息:我发现,在释放模式中关闭所有的编译器优化,使异常消失
有鬼是怎么回事。 有关如何跟踪下来的任何想法?
感谢您的帮助,乔
乔,你有内存泄漏 。
你可能会尝试使用一些内存已被删除。
请参阅本文中的内存泄漏的常见原因,以及如何识别它们,否则,搜索“C ++内存分析器” +你的编译器/平台,它会给适合你的编译器和平台的链接到内存分析器,这将有助于跟踪下降看你的程序是如何使用内存,因为它运行的内存泄漏。
希望这可以帮助。
编辑
如何追查? 这是把我的头顶部,有可能是其他地方更好的建议。 。 。
寻找到代码崩溃,它会访问某些内容的指针(或删除指针)时的情形。 问题是,该指针设有一张)从未被分配B)已被删除。 通过所有引用转到该类型的指针,是他们在副本构建函数/赋值运算符使用?
如果是这样,它的内容被复制或者只是指针? 如果只是指针则包含类试图删除指针? 如果是这样一流的死会成功,第二个会抛出一个访问冲突。
如果你没有明确的代码复制构建函数和operator =,那么你应该隐藏它们(声明私有原型,但没有实现它们),这将停止编译器生成的默认实现为您服务。
当你隐藏起来,你会处处让编译器错误他们正在使用的,它可能是你可以清理这些了,或者你需要实现拷贝构造函数和operator =为每个类。
我在度假从明天开始两个星期,直接今日(按照我的SO用户页面上的链接)给我发电子邮件,如果你已经在这个任何问题。
您是否有已经#defined请在您的代码调试运行任何代码?
即
#ifndef _DEBUG
//release only code such as liscensing code
#endif
这是一两件事,可能会造成问题,我以前也碰到它。
另一种可能性是VS的问题(或任何IDE你正在使用)。 尝试运行.exe文件,而不是直接通过开发利用策略环境释放,看看您是否仍然有同样的问题。
这是一段时间,因为我已经做C ++“愤怒”可以这么说,所以一些(或实际上所有)什么,我下面说的很可能是过时的。
您使用的托管C ++? 如果没有,那么它听起来像一个未初始化的指针。 它曾经是,所有指针都在调试和我回忆起一些关于关闭此行为关闭清零的情况下,但我不记得的全部细节现在。
是字符串超越他们的变量? 不可能用的std :: string,但值得消除。
的可能性夫妇:
我猜想,你在读/写过去本地阵列端。 在调试版本,这可能工作,因为内存不紧紧分配。 在发布版本,这是更容易引起问题,要看是什么旁边的阵列分配。
另一种可能性是,你有一个未初始化的指针地方。 VC默认初始化在调试模式下的局部变量,而不是在释放模式。 因此,这样的代码:
int* p;
if (p != NULL) { /* do something */ }
失败的原因通常在释放模式。
该错误消息强烈建议你有一个内存问题,可能覆盖内存。 这些都是很难找到,但你可以找到一些可能的解决谷歌搜索“的Visual C ++内存破坏工具”。
关于内存破坏的事情是,它是不可预测的。 这并不一定有什么后果,如果确实如此,他们可能不会导致崩溃。 轰然喜欢就是好的,因为它会通知你,你已经有了一个问题。
与调试与发行摆弄,添加或删除部分代码,更改优化选项和象是不可能解决问题的。 即使是这样,它可能突然出现,如果作出任何改变。
所以,你已经有了一个内存损坏问题。 这些几乎总是很难找到,但也有工具。 你需要解决这个问题。
您还可以看看你的店的做法。 你少用安全的构造( new
阵列,而不是vector<>
说)? 你有编码标准,以尽量减少风险? 你有代码审查? 内存损坏可能是阴险和破坏,并且要避免它尽可能。
是什么让你从OS系统异常。 这些都没有处理,因为它们不是C ++异常。 但您可以转换成C ++异常,并抓住他们像一个正常的异常。
这里有一个伟大的文章http://www.thunderguy.com/semicolon/2002/08/15/visual-c-exception-handling/演示了如何创建一个Windows异常类,将捕获该异常(第3页)使用_set_se_translator
方法和抛出一个C ++异常。 伟大的事情是,你可以从EXCEPTION_RECORD结构的堆叠,虽然your'll必须添加该功能来处理结构,但它会帮助你缩小为访问冲突搜索。
我觉得这里的问题是未初始化的局部变量。 在调试模式通常变量初始化得到和你没有得到任何异常。 但由于这种释放模式可能会发生错误。
尝试寻找未初始化的变量其访问权限可能会导致异常。
假设你有布尔局部变量。
bool bRet;
在调试版本BRET将得到initailized为0,你的代码只是正常工作。
但在释放它不会是0,这将是一些随机的值,你的代码可能会做基于布雷。它东西以后可能会导致一个例外,因为BRET值是错误的。