为什么我会遇到“堆腐败”?

时间:2010-04-19 07:54:44

标签: c++ heap-corruption

请不要把这个钉在十字架上。我决定使用char *可能会很好,因为我打算构建的字符串是已知大小的。我也知道如果timeinfo-> tm_hour返回2位以外的东西,那么事情就会发生严重错误。也就是说,当这个函数返回时,VIsual Studio会向我发出关于HEAP CORRUPTION的信息。出了什么问题? (另外,我应该使用stringbuilder吗?)

void cLogger::_writelogmessage(std::string Message)
{
    time_t rawtime;
    struct tm* timeinfo = 0;

    time(&rawtime);
    timeinfo = localtime(&rawtime);

    char* MessageBuffer = new char[Message.length()+11];
    char* msgptr = MessageBuffer;

    _itoa(timeinfo->tm_hour, msgptr, 10);
    msgptr+=2;

    strcpy(msgptr, "::");
    msgptr+=2;

    _itoa(timeinfo->tm_min, msgptr, 10);
    msgptr+=2;

    strcpy(msgptr, "::");
    msgptr+=2;

    _itoa(timeinfo->tm_sec, msgptr, 10);
    msgptr+=2;

    strcpy(msgptr, " ");
    msgptr+=1;

    strcpy(msgptr, Message.c_str());

    _file << MessageBuffer;

    delete[] MessageBuffer;
}

3 个答案:

答案 0 :(得分:7)

您需要再分配一个字节,因为.length的{​​{1}}返回其长度而没有终止NUL,您还需要string中的空格。

即。假设char*返回10.您分配21个字节。将11个字节复制到缓冲区中,然后复制消息,该消息需要10个字节+一个用于NUL。总计:22个字节,你只分配了21个。

答案 1 :(得分:3)

这个

char* MessageBuffer = new char[Message.length()+11];

应该是

char* MessageBuffer = new char[Message.length()+12];

因为您要向缓冲区添加11个额外的字符:

2 for hr
2 for ::
2 for min
2 for ::
2 for sec
1 for " "

你需要一个额外的终止null字符。

答案 2 :(得分:1)

正如其他人所指出的那样,MessageBuffer的大小需要增加一个。

但是,不是以这种方式处理原始字符缓冲区,而是可以直接将时间信息流式传输到_file,而不必先将其放入中间字符串中。如果由于某种原因需要它在中间字符串中,我建议您使用ostringstream类。

void writelogmessage(std::string Message)
{
    time_t rawtime;
    struct tm* timeinfo = 0;

    time(&rawtime);
    timeinfo = localtime(&rawtime);

    std::ostringstream stream;
    stream<<
        timeinfo->tm_hour<<"::"<<
        timeinfo->tm_min<<"::"<<
        timeinfo->tm_sec<<" "<<
        Message;

    _file<<stream.str();
}
相关问题