更改函数内部堆栈上的结构 [英] Changing a struct on the stack inside function

查看:14
本文介绍了更改函数内部堆栈上的结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过 Learn C the Hard Way 工作,目前我被困在 额外学分练习编号 16.

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

#include <stdio.h>#include <stdlib.h>#include <string.h>结构人{字符*名称;年龄;整数高度;重量;};void Person_create(struct Person p,char *name,int age,int height,int weight){p.name = 名称;页数=年龄;p.height = 高度;p.weight = 重量;}void Person_print(struct Person who){printf("姓名: %s
", who.name);printf("	Age: %d
", who.age);printf("	Height: %d
", who.height);printf("	Weight: %d
", who.weight);}int main(int argc, char *argv[]){//制作两个人的结构结构人乔;结构人坦率;个人创建(乔,乔·亚历克斯",32,64,140);个人创建(弗兰克,弗兰克·布兰克",20,72,180);//打印出来Person_print(乔);Person_print(坦率);//让每个人都 20 岁,然后再次打印乔.age += 20;乔.高度-= 2;乔. 体重 += 40;Person_print(乔);坦率的年龄 += 20;坦率的重量+= 20;Person_print(坦率);返回0;}

解决方案

你的代码在运行时产生错误的原因是C通过值传递structs,这意味着内部的以下赋值Person_create 没有效果:

p.name = name;页数=年龄;p.height = 高度;p.weight = 重量;

这不会对 main() 中的 joefrank 进行任何更改,从而导致打印时出现未定义的行为,因为 name<struct Person 的/code> 数据成员仍未初始化.

为了解决这个问题,通过指针传递struct Person,并应用->操作符代替.操作符:

void Person_create(struct Person *p,char *name,int age,int height,int weight){p->名称=名称;p->年龄=年龄;p-> 高度 = 高度;p->重量=重量;}...Person_create(&joe, "乔亚历克斯", 32, 64, 140);//^ 传递一个地址

<块引用>

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

您的代码已经在堆栈上创建了 struct.如果您想完全摆脱指针,请将 Person_create 更改为 *return` 一个新人,如下所示:

struct Person Person_create(char *name,int age,int height,int weight) {结构人 p;p.name = 名称;页数=年龄;p.height = 高度;p.weight = 重量;返回 p;}...joe = Person_create("Joe Alex", 32, 64, 140);

I am working through the Learn C the Hard Way and I am currently stuck on the extra credit exercise number 16.

I am currently trying to adapt their code and making the struct on the stack instead of the heap but my code is giving me segmentation fault and I am unsure why or how to proceed. Any advice is greatly appreciated.

#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
", who.name);
    printf("	Age: %d
", who.age);
    printf("	Height: %d
", who.height);
    printf("	Weight: %d
", 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;
}

解决方案

The reason your code produces errors at runtime is that C passes structs by value, meaning that the following assignments inside Person_create have no effect:

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

This makes no changes to joe and frank inside main(), leading to undefined behavior on printing, because name data member of the struct Person remains uninitialized.

In order to fix this problem, pass struct Person by pointer, and apply -> operator in place of . operator:

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

It is asking for me to not use pointers or malloc, and says as advice to look into creating a struct on the stack

Your code already creates the structs on the stack. If you would like to get rid of pointers completely, change Person_create to *return` a new person, like this:

struct Person Person_create(char *name,int age,int height,int weight) {
    struct Person p;
    p.name = name;
    p.age = age;
    p.height = height;
    p.weight = weight;
    return p;
}
...
joe = Person_create("Joe Alex", 32, 64, 140);

这篇关于更改函数内部堆栈上的结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆