Я редко сталкиваюсь с ошибкой сегмента, когда std :: ofstream выходит из области видимости. У меня есть следующие структуры в моем 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);
}
}
Проблема, с которой я сталкиваюсь, заключается в том, что в некоторых случаях возникает ошибка сегмента, которая возникает в деструкторе std :: ofstream ofs в FileInfo, когда я пытаюсь CloseLogFile
, Это работает много раз. И даже до того, как произошла ошибка SEG (с помощью различных операторов cout), я подтвердил, что std :: ofstream хорош, не вышел из строя, не достиг eof и не плох. Я также подтвердил, что file_map [prefix] существует и присутствует, также выводя функцию FileInfo ToString (). Все они проверяются непосредственно перед удалением в CloseLogFile.
Мой вопрос касается причины ошибки SEG.
Также, когда строка выводится в поток в WriteToFile (), это нормально, если я удаляю объект LogRequest. Как в том, что именно происходит в info->ofs << line << std::endl;
линия?
похоже, что ваш вызов sprintf (timestamp …) перезаписывается на один символ (ноль), что приведет к неопределенному поведению. может или не может быть вашей основной проблемой, хотя, поскольку это в стеке потоков, и ваши предложения находятся в куче …
Других решений пока нет …