2014-10-30 24 views
0

我遇到其中realloc調用似乎修改另一個字符串,keyfile的內容的問題。的realloc()似乎影響已分配的內存

它應該通過的空終止char*(密鑰文件),它包含正上方500個字符來運行。但是,問題是我在while -loop中執行的reallocation似乎修改了密鑰文件的內容。

我試圖與realloc除去動態再分配和代替大小爲200*sizeof(int)代替初始化在for -loop指針。問題仍然存在,keyfile字符串在內存(重新)分配期間被修改,我不知道爲什麼。我已經通過在mallocrealloc語句之前和之後打印keyfile-string來證實了這一點。

注:密鑰文件只包含字符a-z,沒有數字,空格,換行或大寫。只有26個文字,小寫字母。

int **getCharMap(const char *keyfile) { 

    char *alphabet = "abcdefghijklmnopqrstuvwxyz"; 
    int **charmap = malloc(26*sizeof(int)); 

    for (int i = 0; i < 26; i++) { 
     charmap[(int) alphabet[i]] = malloc(sizeof(int)); 
     charmap[(int) alphabet[i]][0] = 0; // place a counter at index 0 
    } 


    int letter; 
    int count = 0; 
    unsigned char c = keyfile[count]; 
    while (c != '\0') { 
     int arr_count = charmap[c][0]; 
     arr_count++; 

     charmap[c] = realloc(charmap[c], (arr_count+1)*sizeof(int)); 

     charmap[c][0] = arr_count; 
     charmap[c][arr_count] = count; 

     c = keyfile[++count]; 
    } 



    // Just inspecting the results for debugging   
    printf("\nCHARMAP\n"); 
    for (int i = 0; i < 26; i++) { 
     letter = (int) alphabet[i]; 
     printf("%c: ", (char) letter); 
     int count = charmap[letter][0]; 

     printf("%d", charmap[letter][0]); 
     if (count > 0) { 
      for (int j = 1; j < count+1; j++) { 
       printf(",%d", charmap[letter][j]); 
      } 
     } 
     printf("\n"); 
    } 
    exit(0); 

    return charmap; 
} 
+2

的valgrind的valgrind的valgrind – bmargulies 2014-10-30 15:59:45

+1

應該是'INT **字符表= malloc的(26 *的sizeof(INT *))'中如果您運行的是64位系統(或者極少數情況下是帶有16位寄存器的32位系統)。 – 2014-10-30 16:01:00

回答

6
charmap[(int) alphabet[i]] = malloc(sizeof(int)); 
charmap[(int) alphabet[i]][0] = 0; // place a counter at index 0 

你正在編寫超出你的charmap數組的末尾。因此,您正在調用未定義的行爲,並且您看到奇怪的效果並不奇怪。

您正在使用的字符代碼作爲索引到數組,但他們不從0開始!他們從a的ASCII碼開始。

你應該使用alphabet[i] - 'a'爲您的數組索引。

+0

您還應該在評論中包含@barakmanos指出的錯誤。 – 2014-10-30 16:06:29

+0

@RSahu:我補充說,作爲答案,以防萬一...... – 2014-10-30 16:12:01

+0

這就是我所需要的,以及這樣一個聰明的解決方案。不勝感激! – krystah 2014-11-05 19:39:31

1

下面一段代碼是麻煩的來源:

int **charmap = malloc(26*sizeof(int)); 
for (int i = 0; i < 26; i++) 
    charmap[...] = ...; 

如果sizeof(int) < sizeof(int*),那麼它將被執行非法存儲器存取操作。

例如,在64位的平臺上,通常情況下是sizeof(int) == 4 < 8 == sizeof(int*)

在這種情況下,通過寫入charmap[13...25],您將訪問未分配的內存。


更改此:

int **charmap = malloc(26*sizeof(int)); 

向該:

int **charmap = malloc(26*sizeof(int*)); 
+0

...或'int ** charmap = malloc(26 * sizeof * charmap);'。 – chux 2014-10-30 16:30:15

+0

@chux:再次 - 感謝您的啓發。我同意在這種情況下使用符號名稱,以便初始化與變量類型無關。 – 2014-10-30 16:36:17

相關問題