【问题标题】:Modifying a char* by pointer in a function gives a crash在函数中通过指针修改 char* 会导致崩溃
【发布时间】:2016-01-21 15:14:36
【问题描述】:

我是 C 的新手,我正在尝试计算动态内存分配以从文件中读取。至少我认为这就是我正在做的事情。

无论如何,这段代码有效:

int readfromfile(FILE *filepointer)
{
    size_t size = 2;
    char *str = (char *) malloc(sizeof(char));
    int character = 0;
    size_t counter = 0;
    while((character = fgetc(filepointer)) != EOF)
    {
        str = (char *) realloc(str, size);
        str[counter] = (char) character;
        size ++;
        counter++;

    }
    str[counter] = '\0';
    printf("+%s+", str);
    free(str);
    return 0;
}

而这段代码没有:

int main()
{
    char *str = (char *) malloc(sizeof(char));
    ...
    readfromfile(ifpointer, &str);
}

int readfromfile(FILE *filepointer, char **str)
{
    size_t size = 2;
    int character = 0;
    size_t counter = 0;
    while((character = fgetc(filepointer)) != EOF)
    {
        *str = (char *) realloc(*str, size);
        *str[counter] = (char) character;
        size ++;
        counter++;
    }
    str[counter] = '\0';
    printf("+%s+", *str);
    free(str);
    return 0;
}

我不明白为什么,因为据我所知,我正在向函数发送指向 char 数组位置的指针并每次都访问数据。编译器没有显示错误消息,它只是循环一次,并且在每次realloc 之后的第二个循环崩溃。分配给第一个值的字符也是垃圾。

我花了很长时间试图让它发挥作用并进行了大量研究,所以如果我错过了解决方案,我深表歉意,但我真的被困在这一点上。

【问题讨论】:

  • 从不转换 malloc 的结果。
  • 它会在添加更多字符时重新分配内存,但不是吗?至于释放内存,我的道歉只是为了检查它是否已被释放,现在被删除了。
  • 你不需要为malloc添加演员
  • @JJJ,是的,我没有看到realloc 部分,抱歉。

标签: c arrays function char dynamic-memory-allocation


【解决方案1】:

你会崩溃,因为

*str[counter] = (char) character;

相同
*(str[counter]) = (char) character;

相对

(*str)[counter] = (char) character;

这实际上是您想要的。阅读Operator Precedence on Wikipedia。您会发现[] 的优先级高于*(取消引用运算符)。

此外,这里的演员表以及对reallocmalloc 的调用都是不必要的。不要忘记检查reallocmalloc等的返回值,看看它们是否分配内存成功。

现在,您还有另一个问题:第二个代码中的free(str); 应该是free(*str);。请注意,在 *str 从函数中释放后,您不应该从 main 读取或写入此内存位置,因为它现在已变为无效,您无法篡改。

【讨论】:

  • 非常感谢!我不敢相信缺少一组括号给我带来了这么多麻烦,我一定要读一读那篇文章。
  • @JJJ 这两种操作的区别可能看起来不是很强烈,但它是完全不同的两种操作,所以两者当然会导致两种不同的结果。
  • @Cool Guy 啊,谢谢,现在摆脱了演员阵容,我也将添加对 realloc/malloc 的检查。
【解决方案2】:

在您的int readfromfile(FILE *filepointer, char **str) 中,参数char **str 实际上与char *str[] 相同,这意味着**str 需要一个字符指针数组。但是你传递给它 char *str 这只是 char 的数组

当您使用 readfromfile(...) 时,您应该这样做(类似于...):

char *str[2] = {"some char array", "another char array"};
readfromfile(ifpointer, str);

或:

char *a = "this char array";
char **str = &a[0];
readfromfile(ifpointer, str);

你会明白的......

【讨论】:

  • "这意味着 **str 需要一个 char 指针数组" -- 不。它需要一个指向 char 的指针(char** ) "但是你传递给它的 char *str 只是一个 char 的数组" -- 不,OP 传递的是 &str 这是一个 char**,这正是readfromfile 的第二个参数需要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
  • 2022-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多