2013-08-20 33 views
1

下面的代碼偶爾在buffer = (char*) realloc(buffer, allocated * sizeof(char));調用(下面標記爲)時會失敗,我通過最初分配1個字符來動態分配char*的空間,並且每次將分配量加倍我已經擁有的內存不足以存儲字符串。realloc僅在未調試時多次調用後纔會失敗

我在我的項目的許多其他部分有非常相似的代碼,具有相同的內存分配策略和調用(僅更改void*的類型,我傳遞給realloc)。

我使用VS2010來調試問題,並且當我在調試模式下啓動程序時,該函數總是成功完成。

但是,從命令行調用程序時,很有可能在一段時間後出現「訪問衝突讀取位置」錯誤後,其中一個調用realloc的調用將失敗 - 儘管它不會發生所有時間,只有在多次調用下面的函數之後纔會發生,並且已經發生了許多重新分配。

什麼是weirder,我在realloc調用之前和之後放置了一些打印,以確定指針位置是否已更改,並且當我這樣做並運行該程序時,realloc的調用會隨機停止失敗。

我在做什麼錯?

TOKEN 
next_token_file(FILE* file, 
       STATE_MACHINE* sm, 
       STATE_MACHINE* wsssm) 
{ 
    char* buffer = (char*) malloc(sizeof(char)); 
    size_t allocated = 1; 
    size_t i = 0; 
    while(1) 
    { 
    /* 
    ... code that increments i by one and messes with sm a bit. Does nothing to the buffer. 
    */ 
     // XXX: This fails when using realloc. Why? 
     if(i + 1 >= allocated) 
     { 
      allocated = allocated << 1; 
      buffer = (char*) realloc(buffer, allocated * sizeof(char)); 
     } 
     buffer[i] = sm->current_state->state; 
    /* 
    ... more code that doesn't concern the buffer 
    */ 
    } 
    // Null-terminate string. 
    buffer[++i] = 0; 
    TOKEN t = {ret, buffer}; 
    return t; 
} 
+1

不應此'爲size_t分配= 1;''被分配的size_t = 16;'? – alk

+0

這就是我的猜測,要麼他確實想在第一輪中從16個字符減少到2個(這將是......奇怪的)。 – WhozCraig

回答

3

由於這些線

char* buffer = (char*) malloc(16 * sizeof(char)); 
size_t allocated = 1; 

程序收縮buffer首4重新分配。所以程序寫入從i=16未分配的內存上,這是未定義的行爲,所以任何事情都可能發生。此外,這很可能會破壞內存管理,從而導致realloc()失敗。

你可能想改變這兩條線爲:

size_t allocated = 16; /* or = 1 if the 16 was a typo. */ 
char * buffer = malloc(allocated); 

其他說明:

它交給最後一個音符,下面的修改應適用

char * buffer = malloc(allocated); 

可能變成:

char * buffer = malloc(allocated); 
if (NULL == buffer) 
{ 
    /* Error handling goes here. */ 
} 

buffer = (char*) realloc(buffer, allocated * sizeof(char)); 

可能變成:

{ 
    char * pctmp = realloc(buffer, allocated); 
    if (NULL == pctmp) 
    { 
    /* Error handling goes here. */ 
    } 
    else 
    { 
    buffer = pctmp; 
    } 
} 
+0

sizeof(char)總是0?請什麼?! – dhein

+0

sizeof(char)從c99開始就是基於它,因爲它必須是1字節,所以你指向sizeof(char)的地方總是0? – dhein

+0

@Zaibis:Ouch ...'0'是一個錯字。固定。 – alk

0

我不知道,當你增加或減少我。 但我敢打賭,根據這個片段,你的問題是:你的重新分配無限期,並且因爲你沒有檢查realloc是否返回NULL,這會使你的程序崩潰;)

正如所有人所說,即使是不好運行pritf的符合它,你違反你的記憶塊。這將通過重新分配已被覆蓋範圍之外的內存地址(除了它的UB)

或者如果你嘗試工作,如果返回值無效(什麼時候返回NULL,會發生什麼,因爲你沒有檢查它) 或者,如果你請求零區(大小參數爲0),並且你返回一個非零指針,你使用那個。 但第二種情況可能不會發生在您的程序;)

1

更多的評論,而不是答案,但我沒有50分來評論。

此:

char* buffer = (char*) malloc(16 * sizeof(char)); 

應該是

char* buffer = (char*) malloc(1 * sizeof(char)); 

allocated = 16. 
+0

不要施加'malloc/calloc/realloc'的結果,因爲它沒有必要也不推薦:http://stackoverflow.com/a/605858/694576 – alk

相關問題