最近接手一个老项目,在老项目中使用了map存储缓存数据,如下:
#include "conf.h" int Frame::parse() { std::map<string, int64_t> tmpString; tmpString.insert(std::map<string, int64_t>::value_type(string("0000"), 12123323)); tmpString.insert(std::map<string, int64_t>::value_type(string("1111"), 54678456)); //Crashes here. tmpString.insert(std::map<string, int64_t>::value_type(string("2222"), 45654548)); }
结果发现每次在insert第二次时程序core。
堆栈如下:
Thread [3] 29672 [core: 2] (Suspended : Signal : SIGSEGV:Segmentation fault) std::basic_string<char, std::char_traits<char>, std::allocator<char> >::compare(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const at 0x354669c47d std::operator< <char, std::char_traits<char>, std::allocator<char> >() at basic_string.h:2,317 0x449d91 std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::operator() at stl_function.h:230 0x44a46b std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, unsigned long>, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, unsigned long> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, unsigned long> > >::_M_insert_unique() at stl_tree.h:1,170 0x44ef40 std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned long, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, unsigned long> > >::insert() at stl_map.h:500 0x44e9f5 Frame::parse() at AnySDFrame.cpp:220 0x44df6b
查找了一上午也没找到原因。最后在stackoverflow中找到了相同的问题,结果找到了原因。
在“conf.h”文件中,我定义了一些结构体,并使用了#pragma pack(4)来设置结构体内存对齐,如下:
#include <string> #pragma pack (4) typedef struct { .... }
原因是:没有在“conf.h”文件中没有用“#pragma pack()”恢复字节对齐,导致包含“conf.h”文件的文件都是以4字节对齐,这样可能导致map insert函数报错。
stackoverflow中也说明了器错误的应用头文件,导致了这一问题:
Problem solved.
Thought I‘d add it here on the off chance anyone else ever does the same thing.
I slowly removed files in my project to try and find the offending file. I was thinking that it must be something defined in a header file that was causing issues (like a static). It took a long time but I think I‘ve found it. I had a header file that defines
a number of structs. These are serialized to the wire so I had them 1 byte aligned using #pragma pack (push) which I put at the top of the file and #pragma pack (pop) at the bottom. But I then added a couple of #include statements after the first #pragma definition
meaning that these includes were aligned incorrectly and caused some nondeterministic behavior. Thanks everyone that had a look. Should probably use the attribute syntax
and I wouldn‘t had the problem. Offending code is below for completeness.
例如下代码:
#pragma pack (push)
#pragma pack (1)
#include <string> //Wrong place for includes!
#include <Units.h>
typedef struct
{
....
}
#pragma pack (pop)
Thanks to everyone who had a look at initial problem.
参考:http://stackoverflow.com/questions/13153047/memory-corruption-due-to-pragma-pack-error-std-map-corruption-crashing-on-in