2010-04-19 72 views
2

請不要把這個釘在十字架上。我決定使用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; 
} 
+0

好像你忘記了字符串末尾的NUL。關閉一個。 – jrockway 2010-04-19 07:56:27

+0

@jrockway不會在Message.c_str()中添加空字符? – User2400 2010-04-19 07:58:28

+2

'/我準備釘子和錘子' – 2010-04-19 07:59:46

回答

7

您需要分配一個多字節,因爲string.length返回其長度而不終止NUL,而您也需要在char*空間。

I.e.假設Message.length()返回10.您分配21個字節。複製11個字節到緩衝區,然後複製消息,這需要10個字節+一個NUL。總計:22個字節,並且您只分配了21個字節。

+0

當然!很簡單。 :) – User2400 2010-04-19 08:01:05

+2

@Michael:他最後一次調用是一個'strcpy',它*確實將NUL放在末尾 – 2010-04-19 08:48:39

+0

確實..評論被刪除。 – 2010-04-20 07:46:54

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字符。

1

正如其他人指出的,MessageBuffer的大小需要增加一個。

但是,不是以這種方式處理原始字符緩衝區,您可以直接將時間信息直接流到_file,而不必先將其放入中間字符串。如果因爲某種原因需要中間字符串,我建議您使用ostringstream類。

​​