Where in memory are my variables stored in C?
考虑到内存分为四个部分:数据、堆、堆栈和代码,全局变量、静态变量、常量数据类型、局部变量(在函数中定义和声明)、变量(在主函数中)、指针和动态分配空间(使用malloc和calloc)在哪里存储在内存中?
我认为它们将按如下方式分配:
- 全局变量----->数据
- 静态变量----->数据
- 常量数据类型----->代码
- 局部变量(在函数中声明和定义)------>堆栈
- 在主函数中声明和定义的变量----->堆
- 指针(例如,
char *arr 、int *arr )------>堆 - 动态分配空间(使用malloc和calloc)------>堆栈
我只是从C的角度来看这些变量。
如果我错了,请纠正我,因为我是新来的C。
你有一些权利,但写这些问题的人至少欺骗了你一个问题:
- 全局变量----->数据(正确)
- 静态变量----->数据(正确)
- 常量数据类型----->代码和/或数据。当常量本身存储在数据段中,并且对它的引用将嵌入到代码中时,请考虑字符串文本。
- 局部变量(在函数中声明和定义)------>堆栈(正确)
- 在
main 函数中声明和定义的变量----->heapalso stack(老师试图欺骗你) - 指针(例如:
char *arr ,int *arr )------heapdata or stack,具体取决于上下文。c允许您声明一个全局或static 指针,在这种情况下,指针本身将结束在数据段中。 - 动态分配的空间(使用
malloc 、calloc 、realloc ------>stackheap
值得一提的是,"堆栈"正式称为"自动存储类"。
对于那些有兴趣了解这些记忆片段的未来访问者,我在C中写下关于5个记忆片段的重要要点:
有些人抬头:
- 局部变量(在C中也称为自动变量)
- 全局变量
- 静态变量
- 您可以有全局静态变量或局部静态变量,但上面三个是父类型。
C中的5个内存段:
1。代码段- 代码段,也称为文本段,是内存中包含经常执行的代码的区域。
- 代码段通常是只读的,以避免被诸如缓冲区溢出等编程错误覆盖的风险。
- 代码段不包含程序变量,如局部变量(在C中也称为自动变量)、全局变量等。
- 基于C实现,代码段还可以包含只读字符串文本。例如,在执行
printf("Hello, world") 操作时,将在代码/文本段中创建字符串"hello,world"。您可以在Linux操作系统中使用size 命令来验证这一点。 - 进一步阅读
数据段
数据段分为以下两部分,通常位于堆区域下方或堆栈上方的某些实现中,但数据段从不位于堆和堆栈区域之间。
2。未初始化的数据段- 此段也称为BSS。
- 这是内存的一部分,其中包含:
- 未初始化的全局变量(包括指针变量)
- 未初始化的常量全局变量。
- 未初始化的局部静态变量。
- 任何未初始化的全局或静态局部变量都将存储在未初始化的数据段中。
- 例如:全局变量EDCOX1×2或静态局部变量EDCOX1(3)将存储在未初始化的数据段中。
- 如果声明一个全局变量,并将其初始化为EDCOX1、4、EDCOX1、5、那么它将进入未初始化的数据段或BSS。
- 进一步阅读
三。初始化数据段
- 此段存储:
- 初始化全局变量(包括指针变量)
- 已初始化常量全局变量。
- 已初始化本地静态变量。
- 例如:全局变量
int globalVar = 1; 或静态局部变量static int localStatic = 1; 将存储在初始化的数据段中。 - 该段可进一步分为初始化只读区和初始化读写区。初始化的常量全局变量将进入初始化的只读区域,而在运行时可以修改其值的变量将进入初始化的读写区域。
- 此段的大小由程序源代码中的值的大小决定,在运行时不会更改。
- 进一步阅读
4。栈段
- 堆栈段用于存储在函数内部创建的变量(函数可以是主函数或用户定义函数),变量如下
- 函数的局部变量(包括指针变量)
- 传递给函数的参数
- 返回地址
- 函数执行完成后,将删除存储在堆栈中的变量。
- 进一步阅读
5。堆段
- 此段用于支持动态内存分配。如果程序员想动态地分配一些内存,那么在C语言中,可以使用
malloc 、calloc 或realloc 方法来完成。 - 例如,当
int* prt = malloc(sizeof(int) * 2) 时,堆中会分配8个字节,该位置的内存地址将返回并存储在ptr 变量中。根据声明/使用的方式,ptr 变量将位于堆栈或数据段上。 - 进一步阅读
纠正错误的句子
1 | constant data types -----> code //wrong |
局部常量变量----->堆栈
初始化的全局常量变量----->数据段
未初始化的全局常量变量----->BSS
1 | variables declared and defined in main function -----> heap //wrong |
在主函数中声明和定义的变量----->堆栈
1 2 3 |
指针(例如char*arr,int*arr)------>该指针变量的大小将在堆栈中。
假设您正在动态分配n字节的内存(使用
注意:指针变量可以指向任何段的内存。
1 2 3 4 5 6 7 8 9 10 11 | int x = 10; void func() { int a = 0; int *p = &a: //Now its pointing the memory of stack int *p2 = &x; //Now its pointing the memory of data segment chat *name ="ashok" //Now its pointing the constant string literal //which is actually present in text segment. char *name2 = malloc(10); //Now its pointing memory in heap ... } |
动态分配的空间(使用malloc、calloc)------>堆
一种流行的桌面架构将进程的虚拟内存分为几个部分:
文本段:包含可执行代码。指令指针接受此范围内的值。
数据段:包含全局变量(即具有静态链接的对象)。细分为只读数据(如字符串常量)和未初始化数据("BSS")。
堆栈段:包含程序的动态内存,即所有线程的空闲存储("堆")和本地堆栈帧。传统上,C堆栈和C堆都是从相反的一端增长到堆栈段的,但是我相信实践已经被放弃了,因为它太不安全了。
C程序通常将具有静态存储持续时间的对象放入数据段,在空闲存储区动态分配对象,以及在其所在线程的调用堆栈上自动分配对象。
在其他平台上,如旧的x86实模式或嵌入式设备上,情况明显不同。
I am referring to these variables only from the C perspective.
从C语言的角度来看,所有重要的是范围、范围、链接和访问;项目如何映射到不同的内存段取决于具体的实现,并且会有所不同。语言标准根本不讨论内存段。大多数现代体系结构的作用基本相同:块作用域变量和函数参数将从堆栈中分配,文件作用域和静态变量将从数据或代码段分配,动态内存将从堆中分配,一些常量数据将存储在只读段中等。
- 变量/自动变量--->堆栈部分
- 动态分配变量--->堆部分
- 初始化的全局变量->数据部分
- 未初始化的全局变量->数据段(BSS)
- 静态变量->数据部分
- 字符串常量->文本部分/代码部分
- 功能->文本部分/代码部分
- 文本代码->文本部分/代码部分
- 寄存器->CPU寄存器
- 命令行输入->环境/命令行部分
- 环境变量->环境/命令行部分
pointers(ex:char *arr,int *arr) -------> heap
不,它们可以在堆栈上,也可以在数据段中。他们可以指向任何地方。