为结构及其成员分配内存

1 c malloc struct pointers

我只是进入结构并为它们分配内存.现在我有一些示例代码,就像下面的"学习C艰难的方式"一样开箱即用

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;
}
Run Code Online (Sandbox Code Playgroud)

所以这就是我的理解.在函数中*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;
}
Run Code Online (Sandbox Code Playgroud)
  • 那么导致问题的区别是什么?
  • 我是否也需要单独对成员进行malloc?
  • 是因为变量已经在示例代码中设置了吗?

Sto*_*ica 5

你得到一个段错误,因为你没有传递年龄字段的地址.相反,你复制它的不确定值,scanf以作为一个地址.

一个简单的本地修复:

scanf("%d",&(who->age));
fprintf(file,"Age:%d\n", who->age);
Run Code Online (Sandbox Code Playgroud)

当我们讨论这个主题时,你为字符串分配的内存比你想要的多.sizeof(who->name)是指针的大小,它不小于char它指向的大小.更重要的是,它得到了保证sizeof(char) == 1.因此可以完全简化字符串的分配:

who->name = malloc(STRINGLENGTH);
Run Code Online (Sandbox Code Playgroud)

  • @ThomasChristopherDavies - 防范用户输入非常聪明.防止误用您的API也很聪明.但恕我直言,对语言规范所保证的东西采取防御是愚蠢的:)如果你不能相信*标准中的那个事实,为什么要信任呢? (2认同)