堆内存上的数据结构

4

最近在一次面试中,有人问了我一个问题,让我感到困惑!

“如何在堆内存中初始化结构?” 请问有人能告诉我正确的答案吗?

顺便问一下:栈和堆内存有什么区别? 对于上述问题,有些人可能会问我“如何在栈内存中初始化结构?”

也许这是一个基本的问题,或者可能是一个错误的问题,但我只是好奇想知道!

有人能帮忙吗?


1
重复内容,例如https://dev59.com/hHVD5IYBdhLWcg3wHn2d#79936 - Georg Fritzsche
@gf 这不是重复,因为它不包含别人问我的问题!! - Vijay
这归结为几乎相同的问题,如果你愿意搜索一下,我相信你会找到更好的匹配。 - Georg Fritzsche
我已经搜索过了,但没有找到确切的答案,这促使我提出了这个问题。 - Vijay
不明确:C和C++有不同的答案。 - MSalters
4个回答

7

堆栈用于分配局部变量,若你需要动态分配内存,例如使用malloc(),则需要使用堆。无论哪种情况,都需要确保先初始化结构。可以使用calloc()从堆中分配内存并自动将其清零(而malloc不会)。另外,如果我没有记错,堆栈上的变量也未初始化。


calloc()函数会将内存块中的每一位都初始化为0。但是它并不会初始化结构体。特别是NULL指针并不一定是所有位都为0,我曾经用过一个老的DOS编译器,在这个编译器里NULL指针的所有位都是1。 - Secure
是的,当然你是正确的,我做了初始化等于设置为零的假设。 - Francis Upton IV
在C++中,我们也可以使用new运算符来执行对象的构造函数。构造函数是对象初始化的地方。 - Thomas Matthews

6

堆栈的生命周期与定义它的函数实例完全相同--当该函数实例返回时,该内存可供回收(如果它是一个适当的C++对象并且具有析构函数,那么将调用该析构函数)。堆存储器一直存在,直到明确释放。

“如何初始化结构体”(无论在哪种类型的内存中!)是一个奇特的问题--显然通过其自动调用的C++构造函数(如果有),否则使用memcpy或类似方法--在堆栈或堆上没有区别。


我认为更好的答案是在函数(对于C)或构造函数(对于C ++)中单独初始化每个字段。 - Thomas Matthews
我提到了C++中的ctor,但是在C语言中使用多个赋值还是memcpy / memset / &c并不取决于堆栈区别(在堆栈上,您可以在变量定义中进行“= {...}”初始化,在堆上则不行:也许这就是他们的意思)。 - Alex Martelli

2
struct MyStruct
{
   int foo;
   int bar;
};

...

struct MyStruct* baz = malloc(sizeof(MyStruct));

您现在可以使用 baz,但其成员变量 foo 和 bar 的值未定义。

1
这将为结构体分配内存,但不会初始化字段。问题模糊不清,无法确定结构体是否已经在堆上。 - Thomas Matthews

1

这是我对面试问题的回答:

如何在堆内存中初始化结构体?

  1. C++语言不需要堆。
  2. 在良好的代码中,结构体应该在构造函数中自行初始化,优先使用初始化列表进行初始化。
  3. 使用指向结构体的指针逐个初始化每个字段。问题可能被理解为结构体已经被分配了。
  4. 在C语言中,可以使用calloc,但是这会将每个字节都赋值为零,对于某些对象来说可能不正确。

至于堆和栈之间的区别,栈是一种先进先出的数据结构。对象被推入栈中,然后弹出。堆是一块内存,其中的项几乎是随机分配的。

搜索网络上的内存分配内存池。许多实现将内存区域实现为向堆增长的栈。您从堆中分配的越多,栈的空间就越少,反之亦然。


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