2014-10-30 79 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

相关问题