我有一个包含数组的结构。如下所示:
struct Node
{
int a;
char a1[25];
}obj;
main()
{
struct Node *p = malloc(sizeof(struct Node));
p->a=10;
}
我想知道是否为这段代码分配了两个不同的内存部分,一个来自堆栈用于存储结构节点,另一个来自堆用于存储指针指向的节点p
?
我有一个包含数组的结构。如下所示:
struct Node
{
int a;
char a1[25];
}obj;
main()
{
struct Node *p = malloc(sizeof(struct Node));
p->a=10;
}
我想知道是否为这段代码分配了两个不同的内存部分,一个来自堆栈用于存储结构节点,另一个来自堆用于存储指针指向的节点p
?
这里没有为数组分配堆栈。内部的数组struct Node
存储在堆上的一个连续块中。您可以通过 print 看到这一点sizeof(struct Node)
,它至少等于:
sizeof(int) + sizeof(char) * 25
p
是具有自动存储期限的对象;它的存储在大多数编译器的堆栈中。
它指向一个具有分配存储期限的结构对象;这个结构对象的存储在大多数编译器的堆中。
编辑后:
struct Node
{
int a;
char a1[25];
}obj;
相反,我猜它将分配在数据部分中。这段代码被修改了一点点
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int a;
char a1[25];
}obj;
int global_data;
int main()
{
// struct Node *p = malloc(sizeof(struct Node));
// p->a=10;
obj.a = 10;
return 0;
}
当我们查看汇编代码时。
.file "ada.c"
.comm obj,32,32
.comm global_data,4,4
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
global_data 和 obj 都分配在同一位置。即未初始化的数据部分。将没有机会在堆中分配。因为没有调用 malloc()。
您应该注意到您只是在声明一个结构(结构节点)。
通过声明它,实际上并没有为它保留任何内存。您只是通知编译器存在这样的数据组织。
当你调用 malloc 时,你只保留一些内存来做你想做的任何事情。
现在,如果您要声明:
struct Node{
.....
}myNode;
在这种情况下,内存中的空间确实会分配给 myNode。
要回答您的后续问题,它既不会在堆栈中也不会在堆中分配。
堆可以随着内存分配而增长。堆栈可以随局部变量一起增长。这是一个不会改变大小的全局变量,因此它可以放置在内存中称为数据段的固定位置。
这也是存储静态变量的地方。
为了更深入地了解这个主题,当您使用 Windows 或 Linux 等操作系统时,在您的程序运行之前,它会被复制到 RAM 内存中的某个位置。其中一部分将被称为代码段,只读代码所在的位置,一部分是数据段,这是该变量所在的位置。您的程序可以访问的其余 RAM 将可用于堆和堆栈。
在没有操作系统的嵌入式系统上,程序是直接从 Flash 运行的,所以它的代码段是在 Flash 中编程的。它的数据段分配给可用的 RAM(与堆栈共享)并且根本没有堆(您需要一些内存管理模块才能使堆概念有意义)