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

具有动态数组成员的C结构内存分配位置问题,c,memory,memory-management,dynamic-memory-allocation,C,Memory,Memory Management,Dynamic Memory Allocation,我想知道在这个示例程序中,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.s

我想知道在这个示例程序中,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;
}

您的混淆源于将指针与分配的空间混为一谈。简单地说,指针只是一个变量,它保存一个值,该值描述另一个值在内存中的地址。指针所需的空间由体系结构的最大可寻址空间决定,而不是由分配的内存块决定。参考性地思考

在这种情况下,将在堆栈中分配
foo
,并且结构实例的大小保持不变
malloc
负责为您分配内存,并向分配的空间返回新的内存地址。随后,您将获取该内存地址并将其保存在
arr
成员中

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


现在,考虑到所有这些,存在声明可变大小结构的机制,但是您需要注意在堆中分配结构并显式处理内存。C99标准引入了灵活的数组成员,允许在结构声明中放置一个大小不确定的数组,前提是该数组与另一个成员一起,并作为结构的最后一个成员放置。

如果执行
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的大小

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;
}

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

如果我将foo.arr[I]的值从0更改为4,它会更改任何东西的大小吗?是否在堆上分配foo.arr?改变foo的大小。arr会改变foo的大小吗?@Macher:发布一个新问题或将这些问题包含在原始问题中。这是问答,不是对话。您可以通过检查调试器中的代码和变量来回答自己的问题。@Clifford我不同意您的观点,这是一个新用户,他尝试学习并提出其他问题,以确保正确理解答案。我认为发表评论比用另一个与此直接相关的问题来污染环境要好。但我同意这些额外的问题可以在原问题中添加。@BSO:这是一个关于不在评论中提出后续问题的一般观点。关于答案的问题很公平,但这些都是新问题。“对未来的忠告真的!”克利福德,我同意你的看法。然而,对于一个明显的新来者来说,我的回答相当枯燥和简短。我应该为what提供一个why。
int-arr*
语法无效,请将其更改为
int-arr
。一个有用的惯例是从右到左读取键入内容:“标识符
arr
是指向
*
的指针。