我试图通过scanf()
将字符串读入结构成员。
如果我启动这样的结构,它将编译并运行得很好:
typedef struct list {
char name[10];
...
} List;
List p;
scanf("%s", p.name);
printf("%s\n", p.name);
如果我通过指针启动结构,那么它仍然可以正常编译,但生成的程序崩溃了:
typedef struct list {
char name[10];
...
} List;
List *p;
scanf("%s", p->name);
printf("%s\n", p->name);
为什么会这样?
答案 0 :(得分:1)
如果您将p
声明为类型struct list
,则会自动为其分配struct list
的内存。您可以写入该内存,然后回读您已编写的内容,就像您在第一个示例中所做的那样。
如果您将p
声明为类型struct list *
,则会自动为其分配指针的内存。没有为struct list
分配内存,部分原因是您可能实际上并不需要任何内存 - 您可能希望将指针指向指向通过其他方式分配的struct list
。您可以写入指针并回读您所写的内容,但这不是您在第二段代码中尝试做的事情。您正在尝试写入和读取指针指向的内容,而指针的值仍然是不确定的。这会产生未定义的行为,程序崩溃是一个相当良性的例子。
如果你想使用指针,那么你有两个主要的选择:
struct list
:List list;
List *p = &list;
scanf("%s", p->name);
printf("%s\n", p->name);
struct list
动态分配内存,并在您完成后将其释放:List *p = malloc(sizeof *p);
if (!p) {
// handle allocation failure
} else {
scanf("%s", p->name);
printf("%s\n", p->name);
free(p);
}
答案 1 :(得分:1)
这是sandipan's answer的C版本,因为它是用C ++编写的,你将它标记为C.
List *p = malloc(sizeof(List));
if(!p)
{
//memory allocation failed, handle error here
}
scanf("%s", p->name);
printf("%s\n", p->name);
//do stuff
free(p); //don't leak memory!
答案 2 :(得分:-1)
你需要在第二种情况下为指针(来自堆)分配内存才能使其工作(并在完成时删除分配给指针的内存,以防止内存泄漏)。在第一种情况下,在堆栈上创建局部变量。这是C ++版本:
typedef struct slist{ char name[10]; } SList;
SList *p1 = (SList*)malloc(sizeof(SList));
scanf("%s", p1->name);
printf("%s\n", p1->name);
free(p1);
这是C版:
{{1}}