当流超出范围时偶尔出现SEG故障



当std::of流超出范围时,我很少遇到seg错误问题。我的Logger中有以下结构。h:

        struct LogRequest
        {
            std::string line;
            std::string prefix;
        };
        struct FileInfo
        {
            std::string name;
            std::ofstream ofs;
            int lines;
            std::string ToString()
            {
                return (name + " exists");
        };

在Logger.cpp中,我有以下功能:

void Logger::Log(const std::string line, std::string prefix)
{
    pthread_mutex_lock(&mutex);
        if (file_map.find(prefix) == file_map.end())
        {
            OpenLogFile(prefix);
        }
        LogRequest* request = new LogRequest;
        request->line = line;
        request->prefix = prefix;
        message_queue.push_back(request);
    pthread_mutex_unlock(&mutex);
}
void Logger::OpenLogFile(const std::string& prefix)
{
    //get timestamp to use
    char timestamp[15];
    time_t now;
    time(&now);
    struct tm* current = localtime(&now);
    sprintf(timestamp, "%02u%02u%04u_%02u%02u%02u", (current->tm_mon+1),
        current->tm_mday,(1900 + current->tm_year), current->tm_hour,
        current->tm_min, current->tm_sec);
    FileInfo* info = new FileInfo;
    info->name = "logs/" + prefix + ".log_" + timestamp;
    info->ofs.open(info->name.c_str(), std::ios::out);
    info->lines = 0;
    file_map[prefix] = info;
}
void Logger::CloseLogFile(const std::string& prefix)
{
    delete file_map[prefix];
}

在Logger.cpp的一个线程中,我有。。。

void Logger::WriteToFile()
{
    std::map<std::string, FileInfo* >::iterator it;
    while(run)
    {
        char timestamp[16];
        time_t now;
        time(&now);
        struct tm* current = localtime(&now);
        sprintf(timestamp, "%02u%02u%04u|%02u%02u%02u|", (current->tm_mon+1),
            current->tm_mday,(1900 + current->tm_year), current->tm_hour,
            current->tm_min, current->tm_sec);
        pthread_mutex_lock(&mutex);
            for(it=file_map.begin(); it != file_map.end(); ++it)
            {
                if(it->second->lines > MAX_LINES)
                {
                    CloseLogFile(it->first);
                    OpenLogFile(it->first);
                }
                else
                {
                    int written = 0;
                    while(!message_queue.empty() && written < MESSAGES_PER_WRITE)
                    {
                        LogRequest* request = message_queue.front();
                        message_queue.pop_front();
                        std::string line(timestamp, 16);
                        line.append(request->line);
                        FileInfo* info = file_map[request->prefix];
                        info->ofs << line << std::endl;
                        info->lines++;
                        written++;
                        delete request;
                    }
                }
            }
        pthread_mutex_unlock(&mutex);
        usleep(1000);
    }
}

我遇到的问题是,当我尝试CloseLogFile时,有时会在FileInfo中的std::ofstreamofs的析构函数中抛出一个seg错误。它能起很多作用。甚至在SEG故障发生之前(通过各种cout语句),我已经确认std::of流是好的,没有失败,没有达到eof,也没有坏。我还确认了file_map[prefix]的存在,并且通过输出FileInfo的ToString()也存在。这些都在CloseLogFile中删除之前进行了检查。

我的问题涉及SEG故障的原因。

此外,当这行被输出到WriteToFile()中的ofstream时,如果我删除LogRequest对象,那还好吗。与中一样,info->ofs << line << std::endl;行中到底发生了什么?

看起来您的sprintf(timestamp…)调用被一个字符(null)覆盖,这将导致未定义的行为。可能是也可能不是你的主要问题,因为它在线程堆栈上,而你的ofs在堆上。。。

最新更新