2

所以我开始玩 C 并且到目前为止玩得很开心。

然而,有几件事我无法理解。

我知道这最终会在堆栈上

int i = 0;

我知道这将为堆上的整数保留空间并返回地址

int *i = malloc(sizeof(int));

然而。如果我这样做

int i_one = 1, i_two = 2;
int *arr = calloc(2, sizeof(int));
arr[0] = i_one;
arr[1] = i_two;

i_one 和两个是堆栈分配的,而 arr 在堆上。这是否意味着 arr 会将 i_one 和 2 的值复制到堆上,或者它会简单地保存对堆栈上变量的 2 个引用。我假设它是 alt one 的变体,考虑到(如果我没记错的话)我的堆栈分配的整数将在我退出此函数后立即被释放。

总而言之,当使用 calloc 创建动态分配的数组时。数组中的条目是否也需要分配指针/堆?在我看来这没有意义,因为那样我不会创建一个 int 指针数组吗?是的,我知道指针的大小与 int 相同,所以这个例子有点愚蠢,但你明白了。

谢谢

4

3 回答 3

3

赋值运算符旨在将存储在一个对象中的值分配给另一个对象。

所以在这些赋值语句中

arr[0] = i_one;
arr[1] = i_two;

存储在变量中的值i_one并被i_two复制到数组元素arr[0]和占用的内存中arr[1]。现在,如果您将更改例如存储在变量中i_one的值,那么存储在其中的值arr[0]将不会更改。

如果你想在堆中存储对对象的引用,i_one那么i_two你应该写

int **arr = calloc(2, sizeof(int *));
arr[0] = &i_one;
arr[1] = &i_two;

现在您可以通过以下方式更改例如i_one通过数组元素存储的值arr[0]

*arr[0] = 10;
于 2021-04-29T09:04:19.010 回答
2

你这么说

int *i = malloc(sizeof(int));

这将最终在堆上

其实,事情并没有那么简单……

如果变量i是函数内部的局部变量,那么变量本身的空间将位于“自动存储”中,即堆栈中。但是返回的指针malloc会指向堆。

于 2021-04-29T08:41:07.170 回答
1

我通过打印我所知道的所有相关类型或符号来检查内存映射(最初我使用静态库、动态加载和运行时加载,但它可能有点令人困惑)。

我还创建了两个“堆变量”并打印它们的地址和包含它们地址的本地指针

->->-> 所以你可以看到本地指针在堆栈中,但它们的实际地址在堆的开头。这就是为什么您可以在堆栈框架之外使用这个分配的变量的原因 - 您的本地指针被删除但地址保留在堆中。

这是我的程序输出:

 ------------------COMMAND-LINE------------------
 |*envp--------------------->           140737488347777|
 |*argv--------------------->           140737488347751|
 
 |envp--------------------->            140737488346896|
 |argv--------------------->            140737488346864|
 
 
 ------------------STACK------------------
 |str1--------------------->            140737488346090|
 |alloc_second address----->            140737488346048|
 |alloc_first address------>            140737488346040|
 |const_local_second ------>            140737488346032|
 |const_local_first-------->            140737488346024|
 |argc--------------------->            140737488346012|
 ------------------FUNC-STACK-FRAME------------------
 |fun_var_const------------>            140737488345956|
 |fun_var_second----------->            140737488345952|
 |fun_var------------------>            140737488345948|
 
 
 ------------------HEAP------------------
 
 ------------------------MMS---------------------------------------
 |strlen(library func)----->            140737353401952|
 ----------------------------------------------------------------
 
 |alloc_second------------->                4215488|
 |alloc_first-------------->                4215456|
 
 
 ------------------BSS------------------
 |global_const = 0 -------->                4210812|
 |global_int_first--------->                4210808|
 |global_double_first------>                4210800|
 |static_int_first--------->                4210796|
 |global_int_const--------->                4202504|
 
 |------------------DATA------------------
 |static_int_second-------->                4210784|
 |global_double_second----->                4210776|
 ------------------DATA - READ ONLY------------------
 |const_static_int_second-->                4204408|
 |const_static_int_first--->                4204412|
 |string literal----------->                4202700|
 
 
 ------------------TEXT------------------
 |extern function --------->                4200215|
 |function (define after)-->                4200181|
 |main -------------------->                4199038|
 |static function --------->                4198870|
 
 -----------------------BOTTOM LINE------------------
 
于 2021-04-29T09:17:37.807 回答