C语言 我的变量存储在 C 中的内存中的哪个位置?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14588767/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Where in memory are my variables stored in C?
提问by starkk92
By considering that the memory is divided into four segments: data, heap, stack, and code, where do global variables, static variables, constant data types, local variables (defined and declared in functions), variables (in main function), pointers, and dynamically allocated space (using malloc and calloc) get stored in memory?
考虑到内存分为数据、堆、栈、代码四段,其中全局变量、静态变量、常量数据类型、局部变量(在函数中定义和声明)、变量(在主函数中)、指针,并且动态分配的空间(使用 malloc 和 calloc)会存储在内存中吗?
I think they would be allocated as follows:
我认为它们将被分配如下:
- Global variables -------> data
- Static variables -------> data
- Constant data types -----> code
- Local variables (declared and defined in functions) --------> stack
- Variables declared and defined in main function -----> heap
- Pointers (for example,
char *arr,int *arr) -------> heap - Dynamically allocated space (using malloc and calloc) --------> stack
- 全局变量 -------> 数据
- 静态变量 -------> 数据
- 常量数据类型 -----> 代码
- 局部变量(在函数中声明和定义)--------> 堆栈
- 主函数中声明和定义的变量---->堆
- 指针(例如
char *arr,,int *arr) -------> 堆 - 动态分配空间(使用 malloc 和 calloc)--------> 栈
I am referring to these variables only from the C perspective.
我只是从 C 的角度来指代这些变量。
Please correct me if I am wrong as I am new to C.
如果我错了,请纠正我,因为我是 C 新手。
回答by dasblinkenlight
You got some of these right, but whoever wrote the questions tricked you on at least one question:
你答对了其中一些,但写问题的人至少在一个问题上欺骗了你:
- global variables -------> data (correct)
- static variables -------> data (correct)
- constant data types -----> code and/or data. Consider string literals for a situation when a constant itself would be stored in the data segment, and references to it would be embedded in the code
- local variables(declared and defined in functions) --------> stack (correct)
- variables declared and defined in
mainfunction ----->heapalso stack (the teacher was trying to trick you) - pointers(ex:
char *arr,int *arr) ------->heapdata or stack, depending on the context. C lets you declare a global or astaticpointer, in which case the pointer itself would end up in the data segment. - dynamically allocated space(using
malloc,calloc,realloc) -------->stackheap
- 全局变量 -------> 数据(正确)
- 静态变量 -------> 数据(正确)
- 常量数据类型 -----> 代码和/或数据。当常量本身存储在数据段中,并且对它的引用将嵌入代码中时,请考虑字符串文字
- 局部变量(在函数中声明和定义)--------> 堆栈(正确)
- 在
main函数中声明和定义的变量----->堆也栈(老师想骗你) - 指针(例如:
char *arr,int *arr) ------->堆数据或堆栈,取决于上下文。C 允许您声明全局或static指针,在这种情况下,指针本身将在数据段中结束。 - 动态分配的空间(使用
malloc,calloc,realloc)-------->堆栈堆
It is worth mentioning that "stack" is officially called "automatic storage class".
值得一提的是,“堆栈”的官方名称是“自动存储类”。
回答by hagrawal
For those future visitors who may be interested in knowing about those memory segments, I am writing important points about 5 memory segments in C:
对于那些可能有兴趣了解这些内存段的未来访问者,我正在用 C 编写关于 5 个内存段的要点:
Some heads up:
一些注意事项:
- Whenever a C program is executed some memory is allocated in the RAM for the program execution. This memory is used for storing the frequently executed code (binary data), program variables, etc. The below memory segments talks about the same:
- Typically there are three types of variables:
- Local variables (also called as automatic variables in C)
- Global variables
- Static variables
- You can have global static or local static variables, but the above three are the parent types.
- 每当执行 C 程序时,都会在 RAM 中分配一些内存用于程序执行。该内存用于存储经常执行的代码(二进制数据)、程序变量等。 下面的内存段讨论相同:
- 通常有三种类型的变量:
- 局部变量(在 C 中也称为自动变量)
- 全局变量
- 静态变量
- 您可以拥有全局静态或局部静态变量,但以上三个是父类型。
5 Memory Segments in C:
C 中的 5 个内存段:
1. Code Segment
1. 代码段
- The code segment, also referred as the text segment, is the area of memory which contains the frequently executed code.
- The code segment is often read-only to avoid risk of getting overridden by programming bugs like buffer-overflow, etc.
- The code segment does not contain program variables like local variable (also called as automatic variables in C), global variables, etc.
- Based on the C implementation, the code segment can also contain read-only string literals. For example, when you do
printf("Hello, world")then string "Hello, world" gets created in the code/text segment. You can verify this usingsizecommand in Linux OS. - Further reading
- 代码段,也称为文本段,是包含频繁执行代码的内存区域。
- 代码段通常是只读的,以避免被缓冲区溢出等编程错误覆盖的风险。
- 代码段不包含局部变量(在 C 中也称为自动变量)、全局变量等程序变量。
- 基于 C 实现,代码段还可以包含只读字符串文字。例如,当您这样做时
printf("Hello, world"),将在代码/文本段中创建字符串“Hello, world”。您可以size在 Linux 操作系统中使用命令来验证这一点。 - 进一步阅读
Data Segment
数据段
The data segment is divided in the below two parts and typically lies below the heap area or in some implementations above the stack, but the data segment never lies between the heap and stack area.
数据段分为以下两部分,通常位于堆区域下方或在某些实现中位于堆栈上方,但数据段永远不会位于堆和堆栈区域之间。
2. Uninitialized data segment
2. 未初始化的数据段
- This segment is also known as bss.
- This is the portion of memory which contains:
- Uninitialized global variables(including pointer variables)
- Uninitialized constant global variables.
- Uninitialized local static variables.
- Any global or static local variable which is not initialized will be stored in the uninitialized data segment
- For example: global variable
int globalVar;or static local variablestatic int localStatic;will be stored in the uninitialized data segment. - If you declare a global variable and initialize it as
0orNULLthen still it would go to uninitialized data segment or bss. - Further reading
- 该段也称为bss。
- 这是包含以下内容的内存部分:
- 未初始化的全局变量(包括指针变量)
- 未初始化的常量全局变量。
- 未初始化的局部静态变量。
- 任何未初始化的全局或静态局部变量都将存储在未初始化的数据段中
- 例如:全局变量
int globalVar;或静态局部变量static int localStatic;将存储在未初始化的数据段中。 - 如果您声明一个全局变量并将其初始化为
0或NULL那么它仍然会转到未初始化的数据段或 bss。 - 进一步阅读
3. Initialized data segment
3. 初始化数据段
- This segment stores:
- Initialized global variables(including pointer variables)
- Initialized constant global variables.
- Initialized local static variables.
- For example: global variable
int globalVar = 1;or static local variablestatic int localStatic = 1;will be stored in initialized data segment. - This segment can be further classified into initialized read-only area and initialized read-write area. Initialized constant global variables will go in the initialized read-only area while variables whose values can be modified at runtime will go in the initialized read-write area.
- The size of this segment is determined by the size of the values in the program's source code, and does not change at run time.
- Further reading
- 该段存储:
- 初始化的全局变量(包括指针变量)
- 初始化常量全局变量。
- 初始化的局部静态变量。
- 例如:全局变量
int globalVar = 1;或静态局部变量static int localStatic = 1;将存储在已初始化的数据段中。 - 该段可以进一步分为初始化只读区和初始化读写区。已初始化的常量全局变量将进入已初始化的只读区,而在运行时可以修改其值的变量将进入已初始化的读写区。
- 该段的大小由程序源代码中的值的大小决定,在运行时不会改变。
- 进一步阅读
4. Stack Segment
4. 堆栈段
- Stack segment is used to store variables which are created inside functions (function could be main function or user-defined function), variable like
- Local variablesof the function (including pointer variables)
- Arguments passed to function
- Return address
- Variables stored in the stack will be removed as soon as the function execution finishes.
- Further reading
- 堆栈段用于存储在函数内部创建的变量(函数可以是主函数或用户定义的函数),变量如
- 函数的局部变量(包括指针变量)
- 传递给函数的参数
- 退货地址
- 一旦函数执行完成,存储在堆栈中的变量将被删除。
- 进一步阅读
5. Heap Segment
5. 堆段
- This segment is to support dynamic memory allocation. If the programmer wants to allocate some memory dynamically then in C it is done using the
malloc,calloc, orreallocmethods. - For example, when
int* prt = malloc(sizeof(int) * 2)then eight bytes will be allocated in heap and memory address of that location will be returned and stored inptrvariable. Theptrvariable will be on either the stack or data segment depending on the way it is declared/used. - Further reading
- 该段是为了支持动态内存分配。如果程序员想要分配一些内存动态然后在C中,它是使用完成
malloc,calloc或realloc方法。 - 例如,当
int* prt = malloc(sizeof(int) * 2)将在堆中分配八个字节时,该位置的内存地址将被返回并存储在ptr变量中。该ptr变量将位于堆栈或数据段上,具体取决于它的声明/使用方式。 - 进一步阅读
回答by rashok
Corrected your wrong sentences
更正你的错误句子
constant data types -----> code //wrong
local constant variables -----> stack
局部常量变量 -----> 堆栈
initialized global constant variable -----> data segment
初始化全局常量变量----->数据段
uninitialized global constant variable -----> bss
未初始化的全局常量变量 -----> bss
variables declared and defined in main function -----> heap //wrong
variables declared and defined in main function -----> stack
在主函数中声明和定义的变量 -----> 堆栈
pointers(ex:char *arr,int *arr) -------> heap //wrong
dynamically allocated space(using malloc,calloc) --------> stack //wrong
pointers(ex:char *arr,int *arr) -------> size of that pointer variable will be in stack.
pointers(ex:char *arr,int *arr) -------> 该指针变量的大小将在堆栈中。
Consider that you are allocating memory of n bytes (using mallocor calloc) dynamically and then making pointer variable to point it. Now that nbytes of memory are in heap and the pointer variable requries 4 bytes (if 64 bit machine 8 bytes) which will be in stack to store the starting pointer of the nbytes of memory chunk.
考虑您正在动态分配 n 个字节的内存(使用malloc或calloc),然后使指针变量指向它。现在n内存字节在堆中,指针变量需要 4 个字节(如果 64 位机器为 8 个字节),它将在堆栈中存储n内存块字节的起始指针。
Note : Pointer variables can point the memory of any segment.
注意:指针变量可以指向任何段的内存。
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
...
}
dynamically allocated space(using malloc,calloc) --------> heap
动态分配空间(使用 malloc、calloc)--------> 堆
回答by Kerrek SB
A popular desktop architecture divides a process's virtual memory in several segments:
流行的桌面架构将进程的虚拟内存划分为几个部分:
Text segment: contains the executable code. The instruction pointer takes values in this range.
Data segment: contains global variables (i.e. objects with static linkage). Subdivided in read-only data (such as string constants) and uninitialized data ("BSS").
Stack segment: contains the dynamicmemory for the program, i.e. the free store ("heap") and the local stack frames for all the threads. Traditionally the C stack and C heap used to grow into the stack segment from opposite ends, but I believe that practice has been abandoned because it is too unsafe.
文本段:包含可执行代码。指令指针采用此范围内的值。
数据段:包含全局变量(即具有静态链接的对象)。细分为只读数据(如字符串常量)和未初始化数据(“BSS”)。
堆栈段:包含程序的动态内存,即空闲存储(“堆”)和所有线程的本地堆栈帧。传统上C栈和C堆是从相反的两端向栈段增长的,但是我相信这种做法已经被放弃了,因为它太不安全了。
A C program typically puts objects with static storage duration into the data segment, dynamically allocated objects on the free store, and automatic objects on the call stack of the thread in which it lives.
AC 程序通常将具有静态存储持续时间的对象放入数据段,动态分配的对象放在空闲存储上,自动对象放在它所在线程的调用堆栈上。
On other platforms, such as old x86 real mode or on embedded devices, things can obviously be radically different.
在其他平台上,例如旧的 x86 实模式或嵌入式设备上,情况显然可能完全不同。
回答by John Bode
I am referring to these variables only from the C perspective.
我只是从 C 的角度来指代这些变量。
From the perspective of the C language, all that matters is extent, scope, linkage, and access; exactly how items are mapped to different memory segments is up to the individual implementation, and that will vary. The language standard doesn't talk about memory segments at all. Most modern architectures act mostly the same way; block-scope variables and function arguments will be allocated from the stack, file-scope and static variables will be allocated from a data or code segment, dynamic memory will be allocated from a heap, some constant data will be stored in read-only segments, etc.
从C 语言的角度来看,重要的是范围、范围、链接和访问;项目如何映射到不同的内存段取决于个人的实现,这会有所不同。语言标准不谈论内存段可言。大多数现代架构的行为方式大致相同;块范围变量和函数参数将从堆栈中分配,文件范围和静态变量将从数据或代码段中分配,动态内存将从堆中分配,一些常量数据将存储在只读段中, 等等。
回答by Antti Haapala
One thing one needs to keep in mind about the storage is the as-ifrule. The compiler is not required to put a variable in a specific place - instead it can place it wherever it pleases for as long as the compiled program behaves as ifit were run in the abstract C machine according to the rules of the abstract C machine. This applies to all storage durations. For example:
关于存储需要记住的一件事是as-if规则。编译器不需要将变量放在特定的位置——相反,它可以将它放在任何它喜欢的地方,只要编译的程序表现得好像它根据抽象 C 机器的规则在抽象 C 机器中运行一样。这适用于所有存储期限。例如:
- a variable that is not accessed all can be eliminated completely - it has no storage... anywhere. Example- see how there is
42in the generated assembly code but no sign of404. - a variable with automatic storage duration that does not have its address taken need not be stored in memory at all. An example would be a loop variable.
- a variable that is
constor effectivelyconstneed not be in memory. Example- the compiler can prove thatfoois effectivelyconstand inlines its use into the code.barhas external linkage and the compiler cannot prove that it would not be changed outside the current module, hence it is not inlined. - an object allocated with
mallocneed not reside in memory allocated from heap! Example- notice how the code does not have a call tomallocand neither is the value 42 ever stored in memory, it is kept in a register! - thus an object that has been allocated by
mallocand the reference is lost without deallocating the object withfreeneed notleak memory... - the object allocated by
mallocneed not be within the heap belowthe program break (sbrk(0)) on Unixen...
- 一个没有被全部访问的变量可以完全消除——它没有存储......任何地方。示例- 查看
42生成的汇编代码中如何存在但没有404. - 具有自动存储持续时间的变量根本不需要存储在内存中。一个例子是循环变量。
- 一个在内存中
const或实际上const不需要在内存中的变量。示例- 编译器可以证明这foo是有效的const并将其使用内联到代码中。bar具有外部链接并且编译器无法证明它不会在当前模块之外被更改,因此它不是内联的。 - 分配的对象
malloc不需要驻留在从堆分配的内存中!示例- 请注意代码如何没有调用,malloc值 42 也从未存储在内存中,而是保存在寄存器中! - 因此,一个已经被分配的对象
malloc并且引用丢失了,而不free需要释放内存的对象...... - 分配的对象
malloc不需要在 Unixen 上程序中断 ( )下面的堆内sbrk(0)...
回答by Steve Wellens
pointers(ex:char *arr,int *arr) -------> heap
指针(例如:char *arr,int *arr)-------> 堆
Nope, they can be on the stack or in the data segment. They can point anywhere.
不,它们可以在堆栈上或在数据段中。他们可以指向任何地方。
回答by prashad
- Variables/automatic variables ---> stack section
- Dynamically allocated variables ---> heap section
- Initialised global variables -> data section
- Uninitialised global variables -> data section (bss)
- Static variables -> data section
- String constants -> text section/code section
- Functions -> text section/code section
- Text code -> text section/code section
- Registers -> CPU registers
- Command line inputs -> environmental/command line section
- Environmental variables -> environmental/command line section
- 变量/自动变量 ---> 堆栈部分
- 动态分配的变量 ---> 堆部分
- 初始化的全局变量 -> 数据部分
- 未初始化的全局变量 -> 数据部分 (bss)
- 静态变量 -> 数据部分
- 字符串常量 -> 文本部分/代码部分
- 函数 -> 文本部分/代码部分
- 文本代码 -> 文本部分/代码部分
- 寄存器 -> CPU 寄存器
- 命令行输入 -> 环境/命令行部分
- 环境变量 -> 环境/命令行部分

