我正在进入结构并为它们分配内存。现在我有一些示例代码,它们开箱即用,如下所示" Learn C The Hard Way"
struct Person {
char *name;
int age;
int height;
int weight;
};
struct Person *Person_create(char *name, int age, int height,
int weight)
{
struct Person *who = malloc(sizeof(struct Person));
assert(who != NULL);
who->name = strdup(name);
who->age = age;
who->height = height;
who->weight = weight;
return who;
}
所以这就是我的理解。在函数*Person_create
中,指针*who
接收大小为struct Person
的一块内存的地址。
Struct Person
有4个成员,一个指向字符串和三个整数的指针。由于指针*who
的类型为struct Person
,因此据我所知,它应该知道它有这些成员。
现在我尝试使用自己的代码创建类似的东西。不幸的是,当我尝试scanf()为即将到来的变量int age
的整数时,我得到了段错误。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
#define STRINGLENGTH 30
struct Person {
char *name;
char *food;
int age;
float height;
};
struct Person *createPerson(FILE *file){
struct Person *who = malloc(sizeof(struct Person));
assert(who != NULL);
who->name = malloc(sizeof(who->name)*STRINGLENGTH);
who->food = malloc(sizeof(who->food)*STRINGLENGTH);
printf("What is the name of the person?\n");
scanf("%29s",who->name);
fprintf(file,"Name:%s\n",who->name);
printf("What food do you eat?\n");
scanf("%29s",who->food);
fprintf(file,"Food:%s\n",who->food);
printf("How old are you?\n");
scanf("%d",who->age);
fprintf(file,"Age:%d\n",who->age);
printf("Whats your height?\n");
scanf("%f",who->height);
fprintf(file,"Height:%f\n",who->height);
return who;
}
void freePerson(struct Person *who){
free(who->name);
free(who->food);
free(who);
}
int main(int argc, char *argv[]){
FILE *file;
if((file = fopen("person.txt","a")) == NULL){
perror(NULL);
return EXIT_FAILURE;
}
printf("Creating a person...\n");
struct Person *newPerson = createPerson(file);
freePerson(newPerson);
fclose(file);
return EXIT_SUCCESS;
}
答案 0 :(得分:6)
你得到一个段错误,因为你没有通过年龄字段的地址。相反,您将scanf
的不确定值复制为地址。
一个简单的本地修复:
scanf("%d",&(who->age));
fprintf(file,"Age:%d\n", who->age);
当我们讨论这个主题时,你为字符串分配的内存比你想要的多。 sizeof(who->name)
是指针的大小,不小于它指向的char
的大小。更重要的是,sizeof(char) == 1
保证了这一点。因此可以完全简化字符串的分配:
who->name = malloc(STRINGLENGTH);