如果 C 结构包含指针,它们是否在堆上分配?

问题描述 投票:0回答:1

在我的程序中,我有一个方法可以实例化一个结构并返回类似这样的内容

struct A {
    int a;
    double * dblPtr;
    double ** dblMatrix;
}


struct A initStruct(int a) {
   struct A instance;

   instance.a = a;
   instance.dblPtr = malloc(sizeof(double));
   instance.dblMatrix = malloc(sizeof(double *) * 5);

   for (int i = 0; i < 5; i++) {
      instance.dblMatrix[i] = malloc(sizeof(double));
   }

   return instance
}

int main() {
   struct A a = initStruct(1);
   doOtherStuff(a);
   doMoreStuff(a);
   return 0
}

这个结构体是分配堆还是栈?在我的程序中,我在返回后继续使用该结构,所以我认为它没有分配堆栈,因为当我退出 initStruct 范围时它会被擦除,对吗?

那么它是堆分配的吗? 为什么/如何运作?

我期待它的堆分配。

c struct memory-management heap-memory allocation
1个回答
0
投票

如果 C 结构包含指针,它们是否在堆上分配?

没有。

当您在函数内声明

SomeType SomeName;
时,当程序执行到达该声明时,程序会使用自动分配的存储(通常使用堆栈实现)为该类型的对象分配空间。
SomeType
的类型无关紧要。

您的

struct A
是一个包含
int
double *
double **
的类型(这是实现二维矩阵的糟糕方法)。最终,这些只是字节。当它在堆栈上分配时,它足以容纳
int
double *
double **
,包括编译器为结构布局的任何填充。事实上,其中一些字节将用作指针,这与为结构分配空间无关。

此外,您不应该将指针与动态分配的内存(通常使用堆实现)相关联。指针可以指向静态分配内存中的对象、自动分配内存中的对象、动态分配内存中的对象或线程内存中的对象(函数指针类型可以指向函数)。

这个结构体是分配堆还是栈?

在讨论 C 语义时,您应该将它们称为动态分配1 和自动分配。它们通常使用堆和栈来实现,但也有例外,它们在 C 中的语义是在 C 标准中指定的,不受堆或栈的属性控制。

脚注

1 C 标准使用“已分配”作为动态分配内存的存储持续时间的名称,但这是一个不幸的缩写,因为该术语也用于指保留所有存储持续时间的内存。

© www.soinside.com 2019 - 2024. All rights reserved.