Почему я получаю «кучную коррупцию»? - PullRequest
2 голосов
/ 19 апреля 2010

Пожалуйста, не распинайте меня за это. Я решил, что было бы хорошо использовать char *, потому что строка, которую я собирался создать, имела известный размер. Я также знаю, что если timeinfo-> tm_hour вернет что-то отличное от 2 цифр, то все будет плохо. Тем не менее, когда эта функция возвращает VIsual Studio, я думаю о HEAP CORRUPTION. Что не так? (Кроме того, я должен просто использовать строителя строк?)

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 ]

7 голосов
/ 19 апреля 2010

Вам необходимо выделить еще один байт, поскольку .length из string возвращает его длину без завершающего NUL, для которого вам также необходимо пространство в char*.

т.е. предположим, что Message.length() возвращает 10. Вы выделяете 21 байт. Скопируйте 11 байтов в буфер, затем скопируйте сообщение, которое требует 10 байтов + один для NUL. Всего: 22 байта, и у вас есть только 21 выделенный.

3 голосов
/ 19 апреля 2010

Это

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 char.

1 голос
/ 19 апреля 2010

Как уже отмечали другие, размер 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();
}
...