【问题标题】:std::string tries to free the wrong memorystd::string 试图释放错误的内存
【发布时间】:2013-12-09 21:10:31
【问题描述】:

我在 linux 环境中的 C++ 项目(使用 GCC 4.8.1 编译)中使用 mysql++ 库 (v3.1.0),并有一个 ssqls 对象作为 I 类的类成员 (session_data)已经做了(Session)。一切正常,直到我的类的一个实例被破坏,此时std::string 对象似乎试图释放一些它没有的内存,导致内核介入。下面是给出的堆栈跟踪的一部分失败后由 GDB 处理。

#2  0x00c143ea in abort () from /lib/libc.so.6
#3  0x00c529d5 in __libc_message () from /lib/libc.so.6
#4  0x00c58e31 in malloc_printerr () from /lib/libc.so.6
#5  0x00c5b571 in _int_free () from /lib/libc.so.6
#6  0x0810e43f in operator delete(void*) () at ../../../../gcc-4.8.1/libstdc++-v3/libsupc++/del_op.cc:47
#7  0x081518eb in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_M_destroy(std::allocator<char> const&) ()
    at /include/ext/new_allocator.h:110
#8  0x08151930 in std::string::_Rep::_M_dispose ()
    at /include/bits/basic_string.h:249
#9  0x0815199e in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() ()
    at /include/bits/basic_string.h:539
#10 0x080ac492 in session_data::~session_data() ()
    at sql_tables.h:80
#11 0x080ac537 in Session::~Session() ()
    at session.cpp:5

所有这些析构函数似乎都是即时创建的,因为我无法在其中设置断点,因为根据 GDB,它们不存在。就个人而言,我怀疑这是 GCC 生成的代码中的错误,这让我假设我以某种方式“虐待”了 ssqls 对象。到目前为止,我在一个较小的项目中重现错误的努力都失败了,但如果我确实做到了,我一定会在此处发布该代码。 真的我想知道是否有人知道可能导致此问题的 ssqls 对象内部发生了什么,同时我将继续尝试调试该问题。

用最少的代码编辑。 session_data 完全由 ssqls 宏定义,我这样称呼它:

sql_create_7(session_data,      4,7,    sql_varchar,    id,
                    sql_text,   last_ip,
                    sql_text,   last_user_agent,
                    sql_datetime,   expires,
                    sql_text,   account,
                    sql_text,   messages,
                    sql_text,   login_key)

Session 类通过以下方式填充session_data 的值:

mysqlpp::StoreQueryResult res=query.store();
session=res[0];

session_data session 是一个类成员,query 是一个 mysql++ 查询对象,它确实有来自数据库的数据) 有时session 的值可能会被session=tmp; 行更改(其中 tmp 是另一个 session_data 对象)。在所有其他情况下,session 中的变量按值使用,例如在session.account 中,所以我认为它们不会引起问题。希望这对人们有更多帮助。

【问题讨论】:

  • 我的问题是我不知道哪个代码最好。我的整个项目太大而无法放在这里,但正如问题所说,到目前为止任何较小的版本都不会产生相同的错误。抱歉,我并不是想无益。
  • 我假设malloc_printerr 和/或__libc_message 会打印出某种错误消息——是这样吗?
  • 是的,他们当时似乎打印了程序的整个内存映射,主要涉及加载了哪些库。实际使用的变量似乎只有很少一部分。
  • 查看session_dataSession 的代码可能会有所帮助,以及它们的构造函数、析构函数和操纵器(如果它们是大型类)
  • 好吧,我似乎做的唯一一件事就是用完全相同的代码重新编译,我很高兴地说错误现在已经消失了。我会密切关注这个程序,如果它重新开始,我会回到这里,我仍然无法完成它。感谢您为此提供的所有帮助。

标签: c++ linux gcc stdstring mysql++


【解决方案1】:

我的心理调试技能告诉我,您的 Session 对象被双重删除,或者它没有正确实施规则-(0, 3, 5) 并且它的一个成员被双重删除(最有可能在被浅拷贝或分配之后)。

【讨论】:

  • 拿出 Valgrind!
  • 你说得对,我没有为Session 实现自己的析构函数,尽管我认为没有必要,因为我不使用任何需要特殊处理的指针。我很高兴被告知我错了。
  • @user2649502:这将是“0 规则”的情况。如果所有资源都由成员和基类充分管理,则不需要析构函数或任何其他特殊成员函数。
猜你喜欢
  • 2011-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-11
  • 2023-03-22
  • 1970-01-01
  • 2015-05-05
相关资源
最近更新 更多