【问题标题】:realloc() seems to affect already allocated memoryrealloc() 似乎会影响已分配的内存
【发布时间】:2014-10-30 15:55:19
【问题描述】:

我遇到了一个问题,realloc 的调用似乎修改了另一个字符串 keyfile 的内容。

它应该通过一个以 null 结尾的 char*(密钥文件)运行,其中包含刚刚超过 500 个字符。然而,问题是我在while-loop 中执行的reallocation 似乎修改了密钥文件的内容。

我尝试使用realloc 删除动态重新分配,而是使用200*sizeof(int) 的大小初始化for-循环中的指针。问题仍然存在,keyfile 字符串在(重新)分配内存期间被修改,我不知道为什么。我已经通过在 mallocrealloc 语句之前和之后打印密钥文件字符串来确认这一点。

注意:密钥文件只包含字符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;
}

【问题讨论】:

  • valgrind valgrind valgrind
  • 应该是int **charmap = malloc(26*sizeof(int*)),以防您在 64 位系统上运行(或者在极少数情况下是具有 16 位寄存器的 32 位系统)。

标签: c malloc realloc


【解决方案1】:
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' 作为您的数组索引。

【讨论】:

  • 您还应该在 cmets 中包含@barakmanos 指出的错误。
  • 这正是我所需要的,也是如此聪明的解决方案。赞赏!
【解决方案2】:

下面这段代码是麻烦的根源:

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

如果sizeof(int) &lt; sizeof(int*),那么它将执行非法的内存访问操作。

例如在 64 位平台上,大小写通常为sizeof(int) == 4 &lt; 8 == sizeof(int*)

在这种情况下,通过写入charmap[13...25],您将访问未分配的内存。


改变这个:

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

到这里:

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

【讨论】:

  • ... 或 int **charmap = malloc(26 * sizeof *charmap);.
  • @chux:再次感谢您启发我。我同意在这种情况下使用符号名称,以便初始化独立于变量类型。
猜你喜欢
  • 2018-11-10
  • 2013-08-12
  • 1970-01-01
  • 1970-01-01
  • 2012-01-03
  • 2012-03-20
  • 2020-12-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多