具有 GCC 优化的 C++ 代码导致核心在字符串上具有无效的 free()
Posted
技术标签:
【中文标题】具有 GCC 优化的 C++ 代码导致核心在字符串上具有无效的 free()【英文标题】:C++ code with GCC optimisation causes core with invalid free() on strings 【发布时间】:2013-02-12 17:17:43 【问题描述】:我有使用 gcc (4.1.2) 和 -O2 构建的 C++ 代码。
当这段代码在没有优化的情况下编译和运行时,程序执行没有任何问题。
当使用 O1/O2/O3 编译时,代码将崩溃并出现一个 valgrind 指示无效的空闲。 这已经缩小到函数内部的字符串变量。
代码将读入文件,并迭代内容。 我把所有的处理代码都去掉了,下面的代码sn -p导致核心...
int MyParser::iParseConfig(Config &inConfig)
bool keepGoing = true;
while(keepGoing)
string valueKey = "";
keepGoing = false;
return 0;
当它在未优化的情况下运行时,它可以正常工作。 当我构建并运行此优化后,它将无法正常工作。
看来是 GCC 优化字符串类的方式有问题。
有什么办法可以规避这个问题吗?
【问题讨论】:
你检查了你所有的free()
或delete
电话吗?
我觉得没问题。不过,缺少的 else
子句似乎很可疑。
崩溃时i
的值是多少?如果超过 99,则您的 charIndex
数组存在缓冲区溢出问题。
可以i > 99
??有关将 int
附加到 std::string
的替代方法,请参阅 ***.com/questions/10516196/…
您能否在一个小的独立代码示例中重现此行为,人们可以尝试在他们自己的系统上进行分析?
【参考方案1】:
如果您溢出 charIndex,(当 i 高于 99 时)谁知道您的程序状态是什么...您声明的存储空间不是很大(2 个字符和一个 null)。
【讨论】:
【参考方案2】:我无法解释为什么这段代码在使用优化编译时会为您崩溃,也许i
超过 2 位并且您有缓冲区溢出,也许这是不同的东西,但无论如何我会更改代码:
sprintf(charIndex, "%d", i++);
string valueKey = "";
valueKey.append("Value").append(charIndex);
string value = inConfig.sFindField(valueKey);
像这样:
stringstream ss;
ss << "Value" << i++;
string value(ss.str());
它更像 C++ 并且应该可以工作。试试看。
如果你好奇这是否真的是缓冲区溢出情况,请插入以下行:
assert(i < 99);
在致电printf
之前。或者使用snprintf
:
snprintf(charIndex, sizeof(charIndex), "%d", i++);
或者让你的缓冲区更大。
【讨论】:
一个猜测:优化后,charIndex
被压缩成三个字节。未优化时,charIndex
有一些填充。另一种可能性是优化器正在移动东西,因此溢出的项目正在改变。【参考方案3】:
这是一个错误包含头文件的问题 - 在包含列表中存在重复包含的 MyParser.h 文件。 这在 GCC 优化级别中围绕字符串优化引起了一些奇怪的情况。
【讨论】:
以上是关于具有 GCC 优化的 C++ 代码导致核心在字符串上具有无效的 free()的主要内容,如果未能解决你的问题,请参考以下文章
由于 std::pair 导致的 GCC (MoSync) 中的 C++ 构建错误