我想知道在此示例程序中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;
}
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的大小将保持不变。
您的困惑源于将指针与分配的空间混合在一起。天真地,指针只是一个变量,该变量持有一个值,该值描述了另一个值在内存中的地址。指针所需的空间由体系结构的最大可寻址空间决定,而不是由分配的内存块决定。]
在这种情况下,foo
在堆栈中分配,并且结构实例的大小保持不变。 malloc
正在为您处理内存分配的机制,并将新的内存地址返回到分配的空间。随后,您将使用该内存地址并将其保存在arr
成员中。
此外,堆栈中分配的任何内容本质上都必须是固定大小的。调用函数时需要知道堆栈帧的大小。考虑以下事实:一个过程的每个参数都必须具有已知大小,或者必须是指向堆中分配的某些结构的指针。
现在,所有考虑的因素,都存在声明可变大小结构的机制,但是您需要注意在堆中分配结构并显式处理内存。 C99标准引入了flexible array member
,它允许在结构声明中放置大小不确定的数组,前提是该数组由另一个成员伴随,并作为结构的最后一个成员放置。]