具有动态数组成员在内存中分配位置的C结构

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

我想知道在此示例程序中foo和arr *在哪里分配。 foo是否以恒定大小分配在堆栈上,还是在* arr上使用malloc时它会更改?如果我将foo.arr [i]的值从0更改为4,是否会更改任何大小? foo.arr是否分配在堆上?更改foo.arr的大小是否会更改foo的大小?

typedef struct {
    int size;
    int* arr;
} S;

int main(void) {
    S foo;
    int new_size = 5;
    foo.size = new_size;
    foo.arr = malloc(new_size * sizeof(int));

    free(foo.arr);
    return 0;
}
c memory memory-management dynamic-memory-allocation
2个回答
0
投票

S foo;时,会在由两个int组成的堆栈中分配S类型的元素,一个int通常为32位,因此已分配了64位。然后执行foo.arr = malloc(new_size * sizeof(int));,在堆中分配了一定数量的连续位,现在foo.arr将指向(->)的前32位。

其他答案:

如果将i的foo.arr [i]从0更改为4,是否会更改什么?

否,因为您将只更改内存中的值而不更改大小。

更改foo.arr的大小是否会更改foo的大小?

否,从arr被分配到堆的那一刻起,foo的大小将保持不变。


0
投票

您的困惑源于将指针与分配的空间混合在一起。天真地,指针只是一个变量,该变量持有一个值,该值描述了另一个值在内存中的地址。指针所需的空间由体系结构的最大可寻址空间决定,而不是由分配的内存块决定。]

在这种情况下,foo在堆栈中分配,并且结构实例的大小保持不变。 malloc正在为您处理内存分配的机制,并将新的内存地址返回到分配的空间。随后,您将使用该内存地址并将其保存在arr成员中。

此外,堆栈中分配的任何内容本质上都必须是固定大小的。调用函数时需要知道堆栈帧的大小。考虑以下事实:一个过程的每个参数都必须具有已知大小,或者必须是指向堆中分配的某些结构的指针。

现在,所有考虑的因素,都存在声明可变大小结构的机制,但是您需要注意在堆中分配结构并显式处理内存。 C99标准引入了flexible array member

,它允许在结构声明中放置大小不确定的数组,前提是该数组由另一个成员伴随,并作为结构的最后一个成员放置。]
© www.soinside.com 2019 - 2024. All rights reserved.