字符串太长时出现 AccessViolationException (C++)

Posted

技术标签:

【中文标题】字符串太长时出现 AccessViolationException (C++)【英文标题】:AccessViolationException when string is too long (C++) 【发布时间】:2009-07-07 18:02:50 【问题描述】:

几天前我问了一个类似的问题,但我正在寻找更多的见解。当我向程序中添加字符串时,我收到了 AccessViolationException:

Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at _cexit()
   at <CrtImplementationDetails>.LanguageSupport._UninitializeDefaultDomain(Void * cookie)
   at <CrtImplementationDetails>.LanguageSupport.UninitializeDefaultDomain()
   at <CrtImplementationDetails>.LanguageSupport.DomainUnload(Object source, EventArgs arguments)
   at <CrtImplementationDetails>.ModuleUninitializer.SingletonDomainUnload(Object source, EventArgs arguments)

程序在顶层有一堆 const std::string:

const std::string caseDelimitedOption = "CaseDelimited";
const std::string endOfLineOption = "EndOfLine";
const std::string functionNameDelimitWordsOption = "FunctionNameDelimitWords";
const std::string functionNameStartCaseOption = "FunctionNameStartCase";
const std::string indentStringOption = "IndentString";
const std::string lowerCaseOption = "LowerCase";
const std::string newLineBetweenDoAndWhileOption = "NewLineBetweenDoAndWhile";
const std::string nextLineOption = "NextLine";
const std::string nextLineAsWellAsCloseParenOption = "NextLineAsWellAsCloseParen";
const std::string noBracesAroundSingleStatementBlockOption = "NoBracesAroundSingleStatementBlock";
const std::string openBraceLocationOption = "OpenBraceLocation";
const std::string underscoreDelimitedOption = "UnderscoreDelimited";
const std::string upperCaseOption = "UpperCase";
const std::string whiteSpaceBeforeLeadingCmntOption = "WhiteSpaceBeforeLeadingComment";

如果我将最后一个字符串替换为:

const std::string whiteSpaceBeforeLeadingCmntOption = ""; //"WhiteSpaceBeforeLeadingComment";

然后异常消失。这只是额外的内存(来自字符串)碰到了我程序中其他地方引起的一些坏内存吗?还是和字符串有关的异常?

感谢您的帮助,

【问题讨论】:

我怀疑您的应用程序中其他地方的一些字符串处理出错了,如果遇到空字符串,只是出于某种原因可以正常工作。您将这些字符串用于什么操作? 唯一用到的地方是:line.find(whiteSpaceBeforeLeadingCmntOption) != std::string::npos 【参考方案1】:

我假设这些字符串是全局变量。

您是否尝试从另一个全局变量的构造函数(或从进入 main 之前调用的某个方法)访问这些字符串?

如果是这种情况,您会遇到全局变量初始化顺序在多个编译单元中未定义的问题。有一些解决方案,但有关您的应用程序的更多信息可能会很有用。

首先测试是否输入了 main。

我认为它使用空字符串是一些编译器优化技巧的结果。

【讨论】:

Main 已输入,但感谢您的想法。您可能对优化技巧是正确的,因为当我关闭所有优化时,异常就会消失。嗯.... 尝试将所有这些常量定义为 const char * 而不是 const 字符串,看看会发生什么。 有趣......当我这样做时,我收到一堆链接器错误,说 char * 已经定义。 您需要在头文件中声明它们,然后在单个 .cpp 文件中定义它们。否则你会得到链接器错误。【参考方案2】:

试试

valgrind --leak-check=full your.exe

并记得使用 -g 编译您的应用程序以获取可执行文件中的源代码行。

【讨论】:

【参考方案3】:

问题不在于字符串。在你的程序中的某个地方,你正在阅读或写作越界。这会导致未定义的行为,这意味着程序可能看似正在运行,您可能会遇到访问冲突,或者它可能会因另一个错误而崩溃,或者......可能会发生其他任何事情。

字符串出现的原因仅仅是它巧妙地改变了程序,导致越界访问到达未分配的页面。

【讨论】:

明白了。我希望情况并非如此。

以上是关于字符串太长时出现 AccessViolationException (C++)的主要内容,如果未能解决你的问题,请参考以下文章

当文本太长时,StatusStrip 标签不可见

SwiftUI:当列表太长时,SearchBar 移出边界

加载gif需要太长时间才能加载

echarts pie 图表当名称太长时

在Gitlab CI中部署Helm图表时,如何将节点主机名修复太长时间

不...当 UIButton (Swift) 中的文本太长时