2012-10-09 37 views
0

下面的代碼代碼,但沒有人知道爲什麼這會打破堆? urlencode函數是在其他地方下載的標準庫函數,並且可以按設計運行。在實際的代碼中,我使用動態大小的char數組,因此malloc需求的原因在main中。傳遞char函數打破堆

/* Returns a url-encoded version of str */ 
/* IMPORTANT: be sure to free() the returned string after use */ 
char *urlencode(char *str) { 
    //char *pstr = str, *buf = malloc(strlen(str) * 3 + 1), *pbuf = buf; 
    char *pstr = str, *buf = malloc(strlen(str) * 3 + 1), *pbuf = buf; 
    while (*pstr) { 
    if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') 
     *pbuf++ = *pstr; 
    else if (*pstr == ' ') 
     *pbuf++ = '+'; 
    else 
     *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15); 
    pstr++; 
    } 
    *pbuf = '\0'; 
    return buf; 
} 

int testFunction(char *str) { 
    char *tmpstr; 
    tmpstr = urlencode(str); 
    // Now we do a bunch of stuff 
    // that doesn't use str 
    free(tmpstr); 
    return 0; 
    // At the end of the function, 
    // the debugger shows str equal 
    // to "This is a test" 
} 

int main() { 
    char *str = NULL; 
    str = malloc(100); 
    strcpy(str, "This is a test"); 
    testFunction(str); 
    free(str); // Debugger shows correct value for str, but "free" breaks the heap 
    return 0; 
} 

謝謝。

+1

您是否收到段錯誤?或者是一個雙重的免費/堆腐敗錯誤具體? – PherricOxide

+1

這裏沒問題,但如果你在ASCII範圍之外有'char','to_hex(* pstr >> 4)'可能會引起麻煩,用'0xF'掩蓋它也更安全。 –

+2

適合我,Valgrind不會產生任何錯誤。你確定'//現在我們做了一堆不使用str的東西'的代碼不會損壞堆嗎?你有沒有試過在Valgrind下運行它? –

回答

1

我猜str已經被free(tmpstr);釋放 - 請看看urlencode-功能的行爲。它似乎不會生成一個新的字符串作爲返回值,但將(更改的)輸入字符串傳回。

+2

不,那不是,它是'malloc's'buf'並返回它。 –

0

問題原來是str的初始malloc的大小計算問題,它被執行爲0.感謝您的評論,很遺憾,沒有辦法真正將答案標記爲評論。

如果這是一個不正確的方法來結束這一點,請讓我知道。

+1

我認爲你可以刪除這個問題。在將來,要麼發佈你的真實代碼,要麼驗證示例代碼實際上遭受同樣的問題(如果沒有,差異可能導致你的解決方案)。 – ugoren