从函数内部调用malloc和realloc会产生意外结果

问题描述 投票:1回答:3
#include <stdio.h>
#include <stdlib.h>

char _getline(char *s)
{
    char c;
    s = (char *)malloc(sizeof(char));

    int i;
    for (i = 0; (s[i] = getchar()) != EOF && s[i] != '\n'; ++i)
    {
        s = (char *)realloc(s, (i + 1) * sizeof(char));
    }
    c = s[i];
    s = (char *)realloc(s, (i + 1) * sizeof(char));
    ++i;
    s[i] = '\0';
    return c; 
}

int main()
{
    char *s = "word";
    char c;
    _getline(s);
    printf("%s\n", s);
    free(s);
    return 0;
}

输出为:

input
word
munmap_chunk(): invalid pointer
Aborted (core dumped)

当我在main中执行相同的操作时,我没有得到错误,但是当我尝试打印字符串时,得到了\0。另外,当我尝试将指针的地址传递给_getline时,我遇到了分段错误。这是尝试:

#include <stdio.h>
#include <stdlib.h>

char _getline(char **s)
{
    char c;
    *s = (char *)malloc(sizeof(char));

    int i;
    for (i = 0; (*s[i] = getchar()) != EOF && *s[i] != '\n'; ++i)
    {
        *s = (char *)realloc(*s, (i + 1) * sizeof(char));
    }
    c = *s[i];
    *s = (char *)realloc(*s, (i + 1) * sizeof(char));
    ++i;
    *s[i] = '\0';
    return c; 
}

int main()
{
    char *s = "word";
    char c;
    _getline(&s);
    printf("%s\n", s);
    free(s);
    return 0;
}

我在做什么错?

c pointers malloc realloc
3个回答
3
投票
第一次尝试时,您会误解传递指针的工作方式。当您在s中重新分配_getline时,这只会影响其s,而不会影响mains,因此main打印word,然后尝试free字符串文字,这可以预期结局很差。要解决此问题,请将_getline(s)更改为_getline(&s),使_getline取为char **而不是char *,然后将其对s的所有使用都更改为*s。请注意,更改其所有用途并不是简单的文本替换;在某些情况下,您将不得不使用(*s)。例如,s[i]需要变为(*s)[i]。如果您只执行了*s[i],它将被错误地解析为*(s[i])

0
投票
\xFF您有问题。由于*s[i] = getchar(),数组索引将在指针取消引用之前应用。因此,例如,如果C's operator precedence rules为1,则将i之后的数据视为指向s[0]的指针,并对其取消引用。这很可能是一个完全无效的内存位置。

0
投票
注意:(*s)[i]是C库函数的名称,请不要使用它。
© www.soinside.com 2019 - 2024. All rights reserved.