将指针传递给char *时,realloc()失败。为什么? (因为它是按价值,而不是参考!)

时间:2014-04-13 18:44:18

标签: c string realloc pass-by-value

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

传递指针值的值正常工作,直到realloc()决定需要分配不同的内存空间。我必须在进入函数时只检查指针的地址,而不是注意到它稍后改变了 .................................................. .......

我的程序从stdin获取用户输入,然后将其解析为令牌。 当我读到输入的每个字符时,我拨打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;
    }

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

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;
    }

对于input = alphabet,例如“abcde ... yz”,正确读取用户输入字符串,并且在进入解析阶段时所有内容都符合预期。

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

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

我有点不解为什么会这样。

更令我困惑的是,如果我注释掉addChrToLine的调用并取消注释接下来的三行(执行相同的操作),则没有错误,解析器就完成了。

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

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

1 个答案:

答案 0 :(得分:2)

错误是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);