【问题标题】:How do we use heaps when starting with a stack declaration?从堆栈声明开始时我们如何使用堆?
【发布时间】:2020-08-02 19:39:33
【问题描述】:

我是 C 的初学者,我正在尝试建立自己的学生数据库。在这里,我试图创建一个新学生,并试图了解如何使用堆声明。这是我使用堆栈声明的代码:



student* create_student(char *given_name, char *family_name, int age,
        char* gender, int *promotion)
{

    student s;
    s.given_name = given_name;
    s.family_name = family_name;
    s.age = age;
    strncpy(s.gender, gender, strlen(gender)+1);
    s.promotion = promotion;
    puts("---print inside create_student function---");
    print_student(s);
    puts("---end of print inside");
    return &s;
}

我知道,由于我们在这里使用堆栈,因此信息会在函数之外丢失,但是对于如何将其“转换”为堆,我有点困惑。

[我之前学过 C++,所以我尝试过类似 student *s = new student]

所以我的问题是,我如何将其转换为堆声明,以便将信息保留在函数之外?

【问题讨论】:

  • 如果你使用 new student 之类的东西,你必须使用 C++,而不是 C。
  • 您在为其他人复制字符串时分配了一些指针。你的接口是怎么定义的?字符串的内存来自哪里?谁负责分配和释放它?还。 strncpy(..strlen(gender)+1) 没有任何意义。它破坏了strncpy 的意图。
  • 啊,好吧,我以前做过 C++,我以为你可以在 C 中使用相同的!我找到了类似 malloc 的东西,但真的能理解它
  • 这能回答你的问题吗? Return address of local variable in C
  • 旁白:您的strncpy(s.gender, gender, strlen(gender)+1); 调用等效于strcpy(s.gender, gender);,并且根本不提供缓冲区溢出保护。您需要将复制的数量限制为目标缓冲区的大小,并且还要注意,如果源字符串至少与目标缓冲区一样长,strncpy 不会在目标缓冲区的末尾放置空终止符,所以需要额外的代码来确保目的地为空终止。

标签: c stack heap-memory


【解决方案1】:

正如您所指出的,如果您将student s 保留在堆栈中,则一旦函数返回,内存块就会被释放,您将无法再访问该信息。像这样的变量具有所谓的automatic storage duration

使用堆可以显式管理内存,因此可以在根据请求分配和释放内存时以更灵活的方式存储信息。像这样的变量具有所谓的allocated storage duration

因此,要将您的信息存储在堆中,您可以使用动态内存分配函数,例如 malloc()calloc()

在您的情况下,要使用堆,我们会这样做:

student* create_student(char *given_name, char *family_name, int age,
        char* gender, int *promotion)
{

    student *s = malloc(sizeof(student));
    s->given_name = given_name;
    s->family_name = family_name;
    s->age = age;
    strncpy(s->gender, gender, strlen(gender)+1);
    s->promotion = promotion;
    puts("---print inside create_student function---");
    print_student(s);
    puts("---end of print inside");
    return s;
}

当您不再需要在堆中分配的内存时,您应该使用free() 释放它。

【讨论】:

    猜你喜欢
    • 2013-09-27
    • 2017-06-01
    • 2013-07-11
    • 2012-01-21
    • 1970-01-01
    • 2022-01-14
    • 2016-02-04
    • 2014-04-17
    • 2016-03-30
    相关资源
    最近更新 更多