【问题标题】:Segmentation fault when overloading QDebug::operator<<重载 QDebug::operator<< 时出现分段错误
【发布时间】:2013-11-24 18:53:29
【问题描述】:

我试图为std::string 重载QDebug::operator&lt;&lt;。我知道我们可以使用 std::string::c_str() 函数调试(使用 qDebug())std::string 对象,但我想避免每次都输入 .c_str

这是我的尝试

#include <QDebug>
#include <string>

inline const QDebug& operator<< (const QDebug& qDebugObj, const std::string& str) {
    return qDebugObj << str.c_str();
}

int main()
{
     std::string s = "4444555";
     qDebug() << s;
}

此程序产生分段错误。这段代码有什么问题?

这是堆栈:

#1  0x00000037c407a911 in malloc () from /lib64/libc.so.6
#2  0x00000037ca8bd09d in operator new(unsigned long) () from /usr/lib64/libstdc++.so.6
#3  0x00000037ca89c3c9 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) ()
   from /usr/lib64/libstdc++.so.6
#4  0x00000037ca89cde5 in ?? () from /usr/lib64/libstdc++.so.6
#5  0x00000037ca89cf33 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) () from /usr/lib64/libstdc++.so.6
#6  0x00000000004012ca in operator<< (qDebugObj=..., str="4444555") at main.cpp:5

【问题讨论】:

标签: c++ qt segmentation-fault operator-overloading qdebug


【解决方案1】:

如果您查看 every overloaded output operator,您会看到 none 有一个 const 限定符。这是您的问题,您尝试修改一个常量对象。去掉qDebugObjectconst限定符和返回值。

您应该有关于它的编译器警告,如果没有,那么您需要启用更多警告(至少在使用 GCC/clang 编译时使用 -Wall)。


实际问题,正如 Mike Seymour 在评论中所回答的那样,您的重载将被递归调用,直到您遇到堆栈溢出。

一种绕过方法可能是将字符串转换为其他内容,例如QString

return qDebugObj << QString::fromStdString(str);

【讨论】:

  • 为什么这不是错误?如果没有const_cast 或等效项,这不应该无法编译吗?
  • @BoBTFish 我也这么认为,但显然 OP 设法构建没有错误。
  • @BoBTFish:不,它会将c_str的结果转换回std::string并递归调用该函数,直到堆栈溢出。
  • @Ashot:QT 文档详细定义了如何重载其输出运算符。 qt-project.org/doc/qt-5.0/qtcore/…
  • QString 有一个QString::fromStdString(std::string),应该使用它而不是使用来自 std::string 的 c_str
【解决方案2】:

除了您尝试制作输出流const 之外,您还没有按照QT documentation 中的说明进行操作

// with the fixed output operator
inline QDebug operator<<(QDebug dbg, const std::string& str)
{
    dbg.nospace() << QString::fromStdString(str);
    return dbg.space();
}

QT 希望通过复制(而不是通过引用)传递输出运算符。以前是有原因的,但我不记得是什么了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-10
    • 2019-07-24
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多