我很难搞清楚造成这种段错误的原因。 根据{{3}},它与我的代码中的某些静态变量相关(请参阅下面的堆栈跟踪中的 __ tcf_0 )。 事实是,我的代码中只有一个静态变量,它是单例类的实例(见下文)。
这段代码对我来说似乎是正确的,但是当程序终止时,~Logger()
(行qDebug() << "Segfault";
)会抛出一个段错误。当我尝试以delete
QTextStream*
为例时,会发生同样的事情。但是,使用标准cout
打印到控制台可以很好地工作,也可以使用标准库执行任何其他操作。似乎它只影响一些Qt类。
编辑:似乎问题来自QTextStream
类。的确,qDebug()
使用它。其他不使用它的课程不会导致段错误。
以下是文件和堆栈跟踪:
的main.cpp
#include <QCoreApplication>
#include "Logger.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Logger::getInstance(); // Create Logger instance
return a.exec();
}
Singleton.h
#ifndef SINGLETON_H
#define SINGLETON_H
template <class T>
class Singleton
{
protected:
Singleton() = default;
~Singleton() = default;
public:
static T &getInstance()
{
static T instance; // <----- static variable here
return instance;
}
};
#endif // SINGLETON_H
Logger.h
#ifndef LOGGER_H
#define LOGGER_H
#include "Singleton.h"
class Logger : public Singleton<Logger>
{
friend class Singleton<Logger>;
private:
Logger();
~Logger();
};
#endif // LOGGER_H
Logger.cpp
#include "Logger.h"
#include <QDebug>
#include <iostream>
Logger::Logger() : Singleton<Logger>()
{
}
Logger::~Logger()
{
std::cout << "It works" << std::endl;
qDebug() << "Segfault"; // <----- segfault here
}
堆栈跟踪
0 msvcrt!_msize C:\Windows\syswow64\msvcrt.dll 0x75cff4fc
1 ?? 0x20d0ea8
2 msvcrt!.dllonexit C:\Windows\syswow64\msvcrt.dll 0x75cff52c
3 (anonymous namespace)::Q_QGS_globalInstance::Holder::~Holder 47 0x6b971717
4 ?? 0xd8fc7add
5 mingw_onexit C:\Qt\Qt5.3.0\5.3\mingw482_32\bin\Qt5Cored.dll 0x6b9ae548
6 atexit C:\Qt\Qt5.3.0\5.3\mingw482_32\bin\Qt5Cored.dll 0x6b9ae5af
7 (anonymous namespace)::Q_QGS_globalInstance::innerFunction 47 0x6b971779
8 QGlobalStatic<QCoreGlobalData, (* (anonymous namespace)::Q_QGS_globalInstance::innerFunction), (* & (anonymous namespace)::Q_QGS_globalInstance::guard)>::operator()(void) 128 0x6b971917
9 QCoreGlobalData::instance 63 0x6b9718f2
10 QTextCodec::codecForLocale 680 0x6b97c475
11 QTextStreamPrivate::reset 399 0x6b8ba6be
12 QTextStreamPrivate::QTextStreamPrivate 330 0x6b8ba3ce
13 QTextStream::QTextStream 954 0x6b8bb69b
14 QDebug::Stream::Stream 66 0x6ba17d27
15 QDebug::QDebug 78 0x6ba17dfa
16 QMessageLogger::debug 359 0x6b78cd0e
17 Logger::~Logger Logger.cpp 13 0x401700
18 __tcf_0 Singleton.h 15 0x40168c
19 msvcrt!isspace C:\Windows\syswow64\msvcrt.dll 0x75cfc3e9
20 msvcrt!_cexit C:\Windows\syswow64\msvcrt.dll 0x75d037df
21 ??
答案 0 :(得分:2)
原因很简单,QApplication
在单身破坏之前被销毁,而qDebug
需要QApplication
对象来获取当前的文本编解码器。
这是为什么单身人士有问题的完美例子。
更改代码的方式是在QApplication
对象之前清除单例,或使其成为永恒(这可能无法完全解决问题,其他某些对象可能会在QApplication
被销毁后使用您的单例)。< / p>