浏览 4769 次
锁定老帖子 主题:C++程序coredump及调试过程
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-05-22
最后修改:2010-05-22
class TSimpleString { public: typedef char charT; TSimpleString() : m_pStorage(NULL) {} ~TSimpleString() { clear(); } TSimpleString(const TSimpleString& p) { reset(p.m_pStorage); } TSimpleString(const charT * pStorage) { reset(pStorage); } TSimpleString & operator = (const TSimpleString& p) { reset(p.m_pStorage); return *this; } TSimpleString & operator = (const charT * pStorage) { reset(pStorage); return *this; } bool empty(void) const { return (m_pStorage == NULL); } void clear(void); void reset(const charT * pSrc); const charT * get(void) const; //如果m_pStorage==NULL, return TStringHelper::g_strEmptyString private: charT * m_pStorage; }; void TSimpleString::clear() { if( m_pStorage != NULL ) { delete []m_pStorage; m_pStorage = NULL; } } void TSimpleString::reset(const TSimpleString::charT * pSrc) { if( m_pStorage == pSrc ) return; clear(); size_t nLen = (pSrc == NULL) ? 0 : TStringHelper::length(pSrc); if( nLen > 0 ) { m_pStorage = new charT [nLen + 1]; TStringHelper::strCpyByCount(m_pStorage, pSrc, nLen); } } const TSimpleString::charT * TSimpleString::get(void) const { if( m_pStorage == NULL ) return TStringHelper::g_strEmptyString.c_str(); return m_pStorage; } void onTestSimpleString() { TSimpleString str1; std::cout << "str1:" << str1.get() << std::endl; TSimpleString str2("str2"); std::cout << "str2:" << str2.get() << std::endl; TSimpleString str3(str2); std::cout << "str3:" << str3.get() << std::endl; str3 = "str3"; std::cout << "str3:" << str3.get() << std::endl; TSimpleString str4 = str3; std::cout << "str4:" << str4.get() << std::endl; } 上面这段代码,运行onTestSimpleString()会coredump,运行结果是 引用 str1: *** glibc detected *** free(): invalid pointer: 0x00cacff4 *** Abort 刚开始还看不出哪里的问题,于是想到先让程序coredump,有了core调试就容易很多。 1,切换到root用户,再用ulimit -c 1234567设置生成core 2,执行程序,输出的结果看到已经生成core文件了 引用 str1: *** glibc detected *** free(): invalid pointer: 0x00cacff4 *** 已放弃 (core dumped) 3,分析core 引用 (gdb) bt #0 0x00b687a2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2 #1 0x00bad7a5 in raise () from /lib/tls/libc.so.6 #2 0x00baf209 in abort () from /lib/tls/libc.so.6 #3 0x00be171a in __libc_message () from /lib/tls/libc.so.6 #4 0x00be7fbf in _int_free () from /lib/tls/libc.so.6 #5 0x00be833a in free () from /lib/tls/libc.so.6 #6 0x001dbfd1 in operator delete () from /usr/lib/libstdc++.so.6 #7 0x001dc01d in operator delete[] () from /usr/lib/libstdc++.so.6 #8 0x08052375 in cmx::TSimpleString::clear (this=0xbff2b880) at ../util/testsimplestring.cpp:25 #9 0x080523a2 in cmx::TSimpleString::reset (this=0xbff2b880, pSrc=0x842e4d8 "str2") at ../util/testsimplestring.cpp:35 #10 0x08062aaa in TSimpleString (this=0xbff2b880, pStorage=0x842e4d8 "str2") at ../util/testsimplestring.cpp:8 #11 0x0805249b in cmx::onTestSimpleString () at ../util/testsimplestring.cpp:68 分析core以为是TSimpleString::reset不应该判断if( m_pStorage == pSrc ),但是去掉这个判断再运行还是出错。分析core搞不定,只好用上valgrind,用valgrind一运行,错误的地方就全部出来了。 4,运行valgrind 引用 ==30827== Conditional jump or move depends on uninitialised value(s) ==30827== at 0x8052393: TSimpleString::reset(char const*) (testsimplestring.cpp:32) ==30827== by 0x8062AA9: TSimpleString::TSimpleString(char const*) (testsimplestring.cpp:8) ==30827== by 0x805249A: onTestSimpleString() (testsimplestring.cpp:68) 可看出在第8行根据const charT * pStorage构造TSimpleString时调用了TSimpleString::reset,而在TSimpleString::reset的32行使用了未初始化的m_pStorage。这时再看回TSimpleString(const charT * pStorage) { reset(pStorage); }就知道,确实是还没初始化m_pStorage。杯具阿 TSimpleString(const TSimpleString& p) { reset(p.m_pStorage); } TSimpleString(const charT * pStorage) { reset(pStorage); } 这两行代码都没有初始化就使用了m_pStorage,应该改成 TSimpleString(const TSimpleString& p) : m_pStorage(NULL) { reset(p.m_pStorage); } TSimpleString(const charT * pStorage) : m_pStorage(NULL) { reset(pStorage); } 再说下写这个类的目的: 因为要存储很多长度很短(只有10来个字符)的字符串对象,这些对象一旦保存后就不再修改,并且很多时候这些字符串是空的,所以不想用std::string来保存。因为std::string不管有没有存储内容都要用3个指针,这对于只存储10个字符来说非常浪费。 不知这样实现是否还有问题,欢迎看官拍板 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |