【问题标题】:realloc() fails when passing pointer to char *. Why? (Because it was by-value, not reference!)将指针传递给 char * 时 realloc() 失败。为什么? (因为它是按值,而不是参考!)
【发布时间】:2014-05-27 15:09:28
【问题描述】:

编辑谢谢约阿希姆。使用您指出的函数签名,并传入我的字符串的地址。在函数内部,我使用 *currBuffer 执行了 realloc(),并使用 (*currBuffer)[lenBuffer] 将值放入字符串中... . :)

在 realloc() 决定需要分配不同的内存空间之前,按值传递指针的值工作正常。我一定只是在进入函数时检查了指针的地址,并没有注意到它后来发生了变化。
..................................................... .......

我的程序从标准输入获取用户输入,然后将其解析为标记。 当我阅读输入的每个字符时,我拨打addChrToLine(userInput, charCount-1, (char) inputChr);void addChrToLine (char *currBuffer, int lenBuffer, char inputChr) 的电话,在那里我将新字符添加到字符串中。 后来,当我解析输入时,我在构建解析的字符串时使用了相同的addChrToLine 函数。但是,当解析器调用该函数时,它会在第 25 个字符处出错。

我读取用户输入的代码:

    char * userInput = malloc(sizeof(char));
    int charCount = 0;

LOOP
    if (!(inputChr == LF)) { // ignore the LF character as it denotes end of input line
        charCount++;
        addChrToLine(userInput, charCount-1, (char) inputChr);
        continue;
    }

我将字符添加到当前行的代码:

void addChrToLine (char *currBuffer, int lenBuffer, char inputChr) {

    currBuffer = realloc(currBuffer, sizeof(char) * (lenBuffer +2));
    if (currBuffer == NULL) {
        perror(NULL);
        exit(ENOMEM);
    }
    currBuffer[lenBuffer] = (char) inputChr;
    currBuffer[lenBuffer+1] = (char) '\0';
}

我解析输入的代码:

    char * parsedCmd = malloc(sizeof(char));
    int ndxOutput = 0;

Switch statement inside a loop to handle variety of cases
    char currChr = command[ndxInput];

    if (addChr) {
        ndxOutput++;
        addChrToLine2(parsedCmd,ndxOutput-1,currChr);
//      parsedCmd = realloc(parsedCmd, sizeof(char) * (ndxOutput+2));
//      parsedCmd[ndxOutput] = command[ndxInput];
//      parsedCmd[ndxOutput+1] = '\0';
        addChr = FALSE;
    }

对于输入 = 字母表,例如“abcde...yz”,用户输入字符串被正确读取,并且在进入解析阶段时一切都符合预期。

在将“a”解析为“w”时,char * 指针parsedCmd 正确显示了内容。当我将“x”传递给addChrToLine 时,它会正确放置字符并调整空值的位置。 但是在返回解析器的下一行时,parsedCmd 显示一个空字符串。

指针的内存位置在addChrToLine 期间和调用之后与之前相同(因此 realloc() 没有移动我的数据)。但是,当我查看内存时,字符串的前 8 个字符现在是 0x00,并且字符串在“i”之后是完整的,一直到“w”(没有“x”)。 当代码尝试将“y”添加到 parsedCmd 时,realloc() 语句会发出错误double free or corruption (fasttop): 0x0000000000605160 ***

我有点不明白为什么会这样。

更让我困惑的是,如果我注释掉对addChrToLine 的调用并取消注释接下来的三行(它们做同样的事情),没有错误并且解析器可以正常完成。

很明显,我的指针或内存分配有问题,但我看不出有什么问题。

有人可以帮我理解这里发生了什么吗?

【问题讨论】:

  • 为什么有这么多演员?哦,为什么?
  • 是他们造成的问题吗?
  • 根本不需要演员表。例如,您将char 类型的变量转换为char 类型,因此它可以存储在char 的数组中。
  • 我知道。我正在学习 C 并使用它们来帮助我更快地学习助记符。而且我不想编辑我粘贴的内容。我什至想对此发表评论,因为我知道它会吸引那些会破坏问题真正目的的人。但我选择听起来不咄咄逼人,只是应付发生的事情。

标签: c string realloc pass-by-value


【解决方案1】:

错误在于 C 传递参数按值,这意味着它们被复制。因此,当您在函数中分配给currBuffer 时,您只需分配(和修改)本地副本。当函数返回时,旧的userInput仍然没有改变。

要解决这个问题,您必须通过引用传递指针,这在 C 中使用指针完成,也就是说,您必须将 指针传递给指针

void addChrToLine (char **currBuffer, int lenBuffer, char inputChr);

...

addChrToLine(&userInput, charCount-1, (char) inputChr);

另一种解决方案是返回新指针:

char *addChrToLine (char *currBuffer, int lenBuffer, char inputChr)
{
    ...
    return currBuffer;
}

...

userInput = addChrToLine(userInput, charCount-1, (char) inputChr);

【讨论】:

    猜你喜欢
    • 2015-03-28
    • 2021-12-07
    • 2011-08-10
    • 2016-11-08
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 2017-06-25
    相关资源
    最近更新 更多