S1E39:C语言的内存布局--笔记
#include <stdio.h>#include <stdlib.h>
//鱼C论坛——BaysideLizard写于2023年11月26日
//实验一
int global_uninit_var;
int global_init_var1 = 1;
int global_init_var2 = 2;
int *func(void);
int main()
{
int local_var1;
int local_var2;
static int static_uninit_var;
static int static_init_var = 3;
char *str1 = "abc";
char *str2 = "efg";
int *malloc_var = (int *)malloc(sizeof(int));
printf("实验一\n");
printf("addr of func -> %p\n",func);
printf("addr of str1 -> %p\n",str1);
printf("addr of str2 -> %p\n",str2);
printf("addr of global_init_var1 -> %p\n",&global_init_var1);
printf("addr of global_init_var2 -> %p\n",&global_init_var2);
printf("addr of static_init_var -> %p\n",&static_init_var);
printf("addr of static_uninit_var -> %p\n",&static_uninit_var);
printf("addr of global_uninit_var -> %p\n",&global_uninit_var);
printf("addr of malloc_var -> %p\n",malloc_var);
printf("addr of local_var1 -> %p\n",&local_var1);
printf("addr of local_var2 -> %p\n",&local_var2);
/*C语言的内存布局规律:
内存地址 低 -------> 高
函数字符串常量全局变量(初始化)静态变量(初始化)静态变量(未初始化)全局变量(未初始化)动态申请的变量空间局部变量
代码段数据段bss段堆栈
代码段:存放程序执行代码
数据段:存放已经初始化的全局变量和局部静态变量
BSS(Block Started by Symbol)段:存放未初始化的全局变量,自动初始化为0
堆:手动申请与释放
栈:自动分配与释放
*/
//实验二
int *ptr = NULL;
ptr = func();
printf("\n实验二\nptr -> %d\n",*ptr);
free(ptr);
//实验三
int *ptr1 = NULL;
int *ptr2 = NULL;
ptr1 = (int *)malloc(sizeof(int));
if(ptr1 == NULL)
{
exit(1);
}
ptr2 = (int *)malloc(sizeof(int));
if(ptr2 == NULL)
{
exit(1);
}
printf("\n实验三\n");
printf("stack:&ptr1-%p | &ptr2-%p\n",&ptr1,&ptr2);
printf("heap:ptr1-%p | ptr2-%p\n",ptr1,ptr2);
ptr1 = realloc(ptr1,2 * sizeof(int));
printf("realloc ptr1 -> 2 * sizeof(int):%p\n",ptr1);
ptr1 = realloc(ptr1,20 * sizeof(int));
printf("realloc ptr1 -> 20 * sizeof(int):%p\n",ptr1);
//str1的内存地址取决于realloc的大小
return 0;
}
int *func(void)
{
int *ptr = NULL;
ptr = (int *)malloc(sizeof(int));
if(ptr == NULL)
{
exit(1);
}
*ptr = 123;
return ptr;
}
运行结果:
实验一
addr of func -> 000000000040177F
addr of str1 -> 0000000000404000
addr of str2 -> 0000000000404004
addr of global_init_var1 -> 0000000000403010
addr of global_init_var2 -> 0000000000403014
addr of static_init_var -> 0000000000403018
addr of static_uninit_var -> 0000000000407030
addr of global_uninit_var -> 0000000000407970
addr of malloc_var -> 0000000000C55E60
addr of local_var1 -> 000000000061FDFC
addr of local_var2 -> 000000000061FDF8
实验二
ptr -> 123
实验三
stack:&ptr1-000000000061FDF0 | &ptr2-000000000061FDE8
heap:ptr1-0000000000C56E90 | ptr2-0000000000C56EB0
realloc ptr1 -> 2 * sizeof(int):0000000000C56E90
realloc ptr1 -> 20 * sizeof(int):0000000000C56ED0
Process returned 0 (0x0) execution time : 0.037 s
Press any key to continue.
不过我发现了一个问题,在我的电脑上堆的地址似乎更高,这是由于编译器和操作系统的具体实现方式引起的。具体来说,当你运行程序时,操作系统会为进程分配虚拟地址空间,并将其划分为不同的区域,如代码区、数据区(包括全局变量和静态变量)、堆和栈等。
详见https://fishc.com.cn/thread-236996-1-1.html
在FishC学C的第21天 你的代码主要是用来展示C语言的内存布局的。我会逐一解释相关部分。
首先是实验一,你定义了一些全局变量、局部变量、静态变量和动态申请的变量空间,并打印它们的地址。
- 函数`func`的地址是`0x000000000040177F`
- 字符串常量`str1`的地址是`0x0000000000404000`
- 字符串常量`str2`的地址是`0x0000000000404004`
- 全局变量`global_init_var1`的地址是`0x0000000000403010`
- 全局变量`global_init_var2`的地址是`0x0000000000403014`
- 静态变量`static_init_var`的地址是`0x0000000000403018`
- 静态变量`static_uninit_var`的地址是`0x0000000000407030`
- 未初始化的全局变量`global_uninit_var`的地址是`0x0000000000407970`
- 动态申请的变量空间`malloc_var`的地址是`0x0000000000C55E60`
- 局部变量`local_var1`的地址是`0x000000000061FDFC`
- 局部变量`local_var2`的地址是`0x000000000061FDF8`
然后你提到了C语言的内存布局规律,从低地址到高地址,依次是代码段、数据段、BSS段、堆和栈。
- 代码段:存放程序执行代码
- 数据段:存放已经初始化的全局变量和局部静态变量
- BSS段:存放未初始化的全局变量,自动初始化为0
- 堆:手动申请和释放内存
- 栈:自动分配和释放内存
接下来是实验二,你定义了一个指针`ptr`,并将它赋值为`func`函数的返回值,然后打印`ptr`指向的值。
在`func`函数中,你动态申请了一个整型变量的空间,并将其赋值为123,然后返回指向该空间的指针。
运行结果显示`ptr`指向的值是123。
最后是实验三,你首先定义了两个指针`ptr1`和`ptr2`,然后分别对它们进行了动态内存分配,分别打印它们在栈和堆中的地址。
接着使用`realloc`函数重新分配了`ptr1`的内存空间,将原来的大小改为2倍,然后打印`ptr1`的值。接着又将`ptr1`的大小改为20倍,并再次打印`ptr1`的值。
注意,使用`realloc`重新分配内存时,要确保之前申请的指针不为空,否则会出错。
希望以上解释能帮助你理解内存布局和相关概念。如果还有其他问题,请随时提问。
以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
页:
[1]