我正在开发Linux下的cpp项目,我想构建一个日志系统,将一些重要信息写入文件。所以我使用这个图书馆:log4cpp
这是关于log4cpp的代码:
// class Log head file
class Log
{
public:
explicit Log(const char * infoCategory = nullptr, const string & pattern = string("%d: %p %c %x: %m%n"), const char * filename = "log")
: category(infoCategory == nullptr ? Category::getRoot() : Category::getRoot().getInstance(infoCategory))
{
logFile.open(filename, ios::app);
osAppender = new OstreamAppender("osAppender", &logFile);
patternLayout = new PatternLayout();
patternLayout->setConversionPattern(pattern);
osAppender->setLayout(patternLayout);
category.addAppender(osAppender);
logFile.seekp(0, ios::end);
size = logFile.tellp();
}
~Log()
{
category.shutdown();
logFile.close();
// Do NOT delete osAppender and patternLayout
}
void info(const string & info)
{
category.info(info);
}
private:
ofstream logFile;
streampos size;
Category & category;
OstreamAppender * osAppender;
PatternLayout * patternLayout;
};
现在,我可以使用Log
写下一些内容。例如,有一个类代理,如下所示:
#include "Log.h"
class Agent
{
public:
~Agent()
{
terminate();
}
void initialize()
{
log.info(" initialized.");
}
void terminate()
{
log.info(" terminated.");
}
static Agent & getInstance()
{
static Agent agent;
return agent;
}
Agent()
{
}
private:
Log log;
};
函数getInstance
用于生成“Singleton”。它的构造函数是私有的,因此我们必须调用getInstance
来生成一个对象。由于此对象是静态的,因此它只能初始化一次。
现在在main
,我写了这个:
int main()
{
Agent & agent = Agent::getInstance();
agent.initialize();
return 0;
}
现在如果我运行它,项目将停在函数Log::info
中,我将收到此错误:Signal received: SIGSEGV(Segmentation fault)
令我惊讶的是,如果我删除log.info("terminated.");
或删除log.info("initialized");
,或者我将两个info
移到initialize
或terminate
函数中,则错误将消失。
或者,如果我在函数Agent
中初始化正常main
,则表示我不使用getInstance
,而是执行此操作:Agent agent;
,错误将消失太。
或者,如果我在函数Agent
中新建getInstance
,而不是使用static
,则错误也会消失。
这是我的第一个问题。
我的第二个问题在这里:
请注意,Log
的析构函数中有注释:
// do NOT delete osAppender and patternLayout
我提出了这样的评论,因为我认为它们都是来自new
的指针,所以我可以而且应该删除它们。但如果我删除其中一个或两个,我会收到同样的错误:
Signal received:SIGSEGV
。
答案 0 :(得分:0)
问题解决了。
我遇到了这个问题,因为log
和agent
都是静态的
这意味着它们在函数return 0;
中 main
之后将是免费的,我们无法决定免费的顺序。
在这种情况下,显然在调用agent
的虚函数之前,log
已经空闲,因此当我在虚函数中调用terminate()
时,会出现错误。