在为字符串分配内存时获取SIGSEGV / SIGABRT

时间:2010-11-19 01:40:41

标签: c++ string malloc new-operator

真的不知道该怎么做 - 当我为一个字符串分配内存时,我的程序一直在崩溃,最常见的是这个无害的代码,在其他情况下从来没有引起过问题:

template <class T>
inline string to_string (const T& t, bool use_fixed = false)
{
    stringstream ss;
    if (use_fixed) ss.setf(ios::fixed, ios::floatfield);
    ss << t;
    return ss.str();
}

具体来说,它在'ss&lt;&lt; T”。 t是int,== 0。堆栈跟踪的最后几行看起来像这样(唉,我太新了,无法发布截图):

0   ??  
1   malloc
2   operator new(unsigned int)
3   std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&)
4   std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned int)
5   std::string::reserve(unsigned int)
6   std::basic_stringbuf<char, std::char_traits<char>, std:allocator<char> >::overflow(int)
...

与我的程序不同的唯一可能相关的东西,现在我可以想到它有多个线程,并启动一个子进程,它有多个线程,也调用这个函数。我在Ubuntu 10.04上。谢谢你的考虑 -

马特

2 个答案:

答案 0 :(得分:4)

发生这种情况时的标准答案是“你正在以某种方式破坏内存分配器内部数据结构”,这就是它崩溃的原因。检查你的数组边界,因为如果你在内存块的键之外写,你可能会覆盖你不应该的东西。

答案 1 :(得分:2)

实际上Matias Valdenegro给了你正确答案。但是,他是以某种方式做到的,你不理解它:他说你以某种方式腐蚀了内存分配器的内部数据结构。而这正是你在做的事情。 唯一不理解的事情(Matias没有告诉你):你没有破坏你在这里引用的代码中的堆。你正在腐蚀堆 else 。引用的代码只是触发中止信号,因为这是分配器功能(即新运算符)检测到,您的堆被损坏(其他地方)的点。而这正是为什么 - 与你的评论相反 - C ++'es std :: to_string在这里根本没有用(如果你破坏堆也会有SIGABRT),这就是为什么当你正在研究某些东西时这个bug突然消失的原因其他地方。您显然刚刚修复了导致堆损坏的错误。

找到这种bug的一个很好的工具叫做valgrind,如果你还不知道它,你肯定应该改变它,因为它不仅会告诉你发生了什么,而且还会告诉你bug居住。