在C语言中在堆上分配结构体

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

struct myStruct
{
    int number;
};

void
allocateMem(struct myStruct *struct1)
{
    struct1 = malloc(sizeof(struct myStruct));
    struct1->number = 500;
    printf("struct1->number: %d\n", struct1->number);
}

int
main(int argc, char *argv[])
{
    struct myStruct *struct1 = NULL;
    allocateMem(struct1);
    printf("number: %d\n", struct1->number);
    return 0;
}

大家好,我需要您的帮助。

我想做的是使用堆空间而不是栈空间来分配一个结构体,而且我想在函数内部进行分配。无论我怎么弄,我总是得到一个段错误或几个编译器警告。

我在这里做错了什么,但我无法找出问题所在,我已经在StackOverflow和互联网上寻找与我的问题相关的示例或帖子,但我没有找到任何信息。

如果您能告诉我我做错了什么,或者只是指导我正确的方向,我将非常感激。


谢谢大家的快速和准确的回复。你们说得对,我需要一个指向指针的指针,由于您的帮助,我的代码现在可以工作了。


你正在按值传递地址,需要传递地址的地址。请阅读指向指针的必要性 - Grijesh Chauhan
1
这不是重复的。好吧,至少不是那个问题的重复。 - Rose Kunkel
在 Stack Overflow 上有数百(也许数千)个关于“为什么我对这个按值传递的变量所做的更改不会在调用函数中保留”的线程。 - M.M
3个回答

11
在此功能中,
void
allocateMem(struct myStruct *struct1)
{
    struct1 = malloc(sizeof(struct myStruct));
    struct1->number = 500;
    printf("struct1->number: %d\n", struct1->number);
}

struct1是按值传递的。在函数中对其进行的任何更改都不会从调用函数中可见。

更好的替代方案:

struct myStruct* allocateMem()
{
    struct myStruct *struct1 = malloc(sizeof(struct myStruct));
    struct1->number = 500;
    printf("struct1->number: %d\n", struct1->number);
    return struct1;
}

将调用函数更改为:

int
main(int argc, char *argv[])
{
    struct myStruct *struct1 = allocateMem();
    printf("number: %d\n", struct1->number);

    // Make sure to free the memory.
    free(struct1);

    return 0;
}

5

实际上,指针只是一个整数。当你将struct1传递给函数时,因为struct1为空,实际上你只是将0传递给函数。该值被传递到堆栈中,然后进行堆分配,并使用新地址更新堆栈值。但是,当你从函数返回时,该值就会从堆栈中弹出,而你已经泄漏了该内存。在主函数中,struct1的值(也仍在堆栈中)保持为0(NULL)。因此,如果想要更新该值,必须传递指向指针的指针,或者更容易的方法是从函数中返回malloc'd指针。

以下是一种修改函数使其正常工作的方式:

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

struct myStruct
{
    int number;
};

struct myStruct*
allocateMem()
{
    struct myStruct* struct1 = malloc(sizeof(struct myStruct));
    struct1->number = 500;
    printf("struct1->number: %d\n", struct1->number);
    return struct1;
}

int
main(int argc, char *argv[])
{
    struct myStruct *struct1 = allocateMem();
    printf("number: %d\n", struct1->number);
    return 0;
}

2

由于你在方法中更改了struct1指针,因此你需要将指针返回给调用者或者作为双重指针(调用者的指针地址)传递,例如:

返回:

struct myStruct* allocateMem()
{
    struct myStruct* struct1 = malloc(sizeof(struct myStruct));
    struct1->number = 500;
    printf("struct1->number: %d\n", struct1->number);
    return struct1;
}

双指针:

void allocateMem(struct myStruct **struct1) 
{

按照@Grijesh评论中的分配和使用方法进行操作。

1
此外,可以像这样调用它:allocateMem(&struct1); - Grijesh Chauhan
1
StuartLC,你还应该建议将 struct1 = malloc(sizeof(struct myStruct)); 改为 (*struct1) = malloc(sizeof(struct myStruct));,并更改声明代码。 - Grijesh Chauhan
应该将 struct* allocateMem(){ 改为 struct myStruct* allocateMem(){ - Grijesh Chauhan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接