在函数内部更改堆栈上的结构

时间:2015-07-22 16:24:05

标签: c struct stack

我正在通过以艰难的方式学习C ,目前我仍然坚持extra credit exercise number 16

我目前正在尝试调整他们的代码并在堆栈而不是堆上创建结构但是我的代码给了我分段错误,我不确定为什么或如何继续。非常感谢任何建议。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Person {
    char *name;
    int age;
    int height;
    int weight;
};

void Person_create(struct Person p,char *name,int age,int height,int weight)
{
    p.name = name;
    p.age = age;
    p.height = height;
    p.weight = weight;
}

void Person_print(struct Person who)
{
    printf("Name: %s\n", who.name);
    printf("\tAge: %d\n", who.age);
    printf("\tHeight: %d\n", who.height);
    printf("\tWeight: %d\n", who.weight);
}

int main(int argc, char *argv[])
{
    // make two people structures
    struct Person joe;
    struct Person frank;
    Person_create(
            joe,"Joe Alex",32,64,140);

    Person_create(
            frank,"Frank Blank",20,72,180);

    // print them out
    Person_print(joe);
    Person_print(frank);

    // make everyone age 20 years and print them again
    joe.age += 20;
    joe.height -= 2;
    joe.weight += 40;
    Person_print(joe);

    frank.age += 20;
    frank.weight += 20;
    Person_print(frank);

    return 0;
}

3 个答案:

答案 0 :(得分:4)

您的代码在运行时产生错误的原因是C按值传递struct,这意味着Person_create中的以下分配无效:

p.name = name;
p.age = age;
p.height = height;
p.weight = weight;

这不会对joe内的frankmain()进行任何更改,从而导致打印时出现未定义的行为,因为name的{​​{1}}数据成员仍然未初始化

要解决此问题,请通过指针传递struct Person,并应用struct Person运算符代替->运算符:

.
  

它要求我不要使用指针或malloc,并说是建议在堆栈上创建一个结构

您的代码已在堆栈上创建void Person_create(struct Person *p,char *name,int age,int height,int weight) { p->name = name; p->age = age; p->height = height; p->weight = weight; } ... Person_create(&joe, "Joe Alex", 32, 64, 140); // ^ Pass an address 。如果您想完全摆脱指针,请将struct更改为* return`一个新人,如下所示:

Person_create

答案 1 :(得分:3)

以下列方式定义finction Person_create

void Person_create(struct Person *p, char *name, int age, int height, int weight)
{
    p->name = name;
    p->age = age;
    p->height = height;
    p->weight = weight;
}

并将其称为

Person_create( &joe, "Joe Alex", 32, 64, 140 );

更复杂的方法如下

#include <string.h>
#include <stdlib.h>

//...

void Person_create(struct Person *p, const char *name, int age, int height, int weight)
{
    size_t n = strlen( name );
    p->name = malloc( ( n + 1 ) * sizeof( char ) );
    strcpy( p->name, name );
    p->age = age;
    p->height = height;
    p->weight = weight;
}

但是在这种情况下,当结构的对象离开其范围时,您应该记住释放已分配的内存。

答案 2 :(得分:0)

#include <stdio.h>
#include <stdlib.h>

typedef struct {
        char *name;
        int age;
        int height;
        int weight;
}Person;

void Person_print(Person who)
{
        printf("Name: %s\n", who.name);
        printf("\tAge: %d\n", who.age);
        printf("\tHeight: %d\n", who.height);
        printf("\tWeight: %d\n", who.weight);
}

int main(int argc, char *argv[])
{
        Person joe= {"Joe Alex", 32, 64, 140};
        Person frank={"Joe Alex", 32, 64, 140};

        printf("Joe is at memory location: %p\n", &joe);
        Person_print(joe);

        printf("Frank is at memory location: %p\n", &frank);
        Person_print(frank);

        joe.age += 20;
        joe.height -= 2;
        joe.weight += 40;
        Person_print(joe);

        frank.age += 20;
        frank.weight += 20;
        Person_print(frank);

        return 0;
}

Typedef名为'Person'的结构,然后您不必使用'Person create'。