【发布时间】:2017-03-27 13:21:32
【问题描述】:
我只是进入结构并为它们分配内存。现在我有一些示例代码,它们可以像下面的“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,据我所知,它应该知道它具有这些成员。
现在我尝试用一些自己的代码创建类似的东西。不幸的是,我在尝试为即将到来的变量 int age 扫描 f() 整数时遇到了段错误。
#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;
}
- 那么导致问题的差异是什么?
- 我也需要单独 malloc 成员吗?
- 是不是因为示例代码中已经设置了变量?
【问题讨论】:
-
这是选项 4 - 你没有正确调用
scanf。 -
和往常一样,valgrind 就是答案
-
[不是原因]
who->name = malloc(sizeof(who->name)*STRINGLENGTH);-->>who->name = malloc(STRINGLENGTH);:: 你想分配 STRINGLENGTH 个字符(不是指针) -
顺便说一句,请注意您在Learn C The Hard Way 中提供的示例显示了对断言的严重误用。断言是非常错误的检查合理的运行时错误的工具。它们用于检查 programming 错误。如果您的程序曾经遇到断言失败,这意味着您的程序是错误的。此外,根据您构建代码的方式,甚至可能不会在运行时检查断言的条件,因此您不能将它们用于强制性的函数结果检查。
-
感谢您的宝贵建议!