#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;
}
我在做什么错?
s
中重新分配_getline
时,这只会影响其s
,而不会影响main
的s
,因此main
打印word
,然后尝试free
字符串文字,这可以预期结局很差。要解决此问题,请将_getline(s)
更改为_getline(&s)
,使_getline
取为char **
而不是char *
,然后将其对s
的所有使用都更改为*s
。请注意,更改其所有用途并不是简单的文本替换;在某些情况下,您将不得不使用(*s)
。例如,s[i]
需要变为(*s)[i]
。如果您只执行了*s[i]
,它将被错误地解析为*(s[i])
。\xFF
您有问题。由于*s[i] = getchar()
,数组索引将在指针取消引用之前应用。因此,例如,如果C's operator precedence rules为1,则将i
之后的数据视为指向s[0]
的指针,并对其取消引用。这很可能是一个完全无效的内存位置。(*s)[i]
是C库函数的名称,请不要使用它。