std::string试图释放错误的内存

std::string tries to free the wrong memory

本文关键字:错误 内存 释放 string std      更新时间:2023-10-16

我在linux环境中的C++项目(使用GCC 4.8.1编译)中使用mysql++库(v3.1.0),并有一个ssqls对象作为我创建的类(Session)的类成员(session_data)。一切都很好,直到我的类的一个实例被销毁,这时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中,所以我认为它们不应该引起问题。希望这对人们有更多的帮助。

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