简体   繁体   English

C / C ++程序的内存布局如何?

[英]How is the memory layout of a C/C++ program?

I know that there are sections like Stack, Heap, Code and Data. 我知道有Stack,Heap,Code和Data等部分。 Stack/Heap do they use the same section of memory as they can grow independently? 堆栈/堆是否使用相同的内存部分,因为它们可以独立生长? What is this code section? 这段代码是什么? When I have a function is it a part of the stack or the code section? 当我有一个函数是它的一部分堆栈或代码部分? Also what is this initialized/uninitialized data segment? 这个初始化/未初始化的数据段是什么?

Are there read only memory section available? 是否有只读存储器部分? When I have a const variable, what is actually happening is it that the compiler marks a memory section as read only or does it put into a read only memory section. 当我有一个const变量时,实际发生的是编译器将内存部分标记为只读或将其放入只读内存部分。

Where are static data kept? 静态数据保存在哪里? Where are global data kept? 全球数据保存在哪里?

Any good references/articles for the same? 任何好的参考/文章相同?

I thought the memory sections and layout are OS independent and it has more to do with compiler. 我认为内存部分和布局与操作系统无关,它更多地与编译器有关。 Doesn't Stack, Heap, Code, Data [Initialized, Uninitialized] segment occur in all the OS? 堆栈,堆,代码,数据[初始化,未初始化]段是否出现在所有操作系统中? When there is a static data, what is happening the compiler has understood it is static, what next, what will it do? 当存在静态数据时,编译器发生的事情是静态的,接下来会发生什么呢? It is the compiler which is managing the program and it should know what to do right? 是编译器管理程序,它应该知道该做什么? All compilers shouldn't they follow common standards? 所有编译器都不应该遵循通用标准吗?

There's very little that's actually definitive about C++ memory layouts. 关于C ++内存布局实际上是确定无疑的。 However, most modern OS's use a somewhat similar system, and the segments are separated based on permissions. 但是,大多数现代操作系统使用的是类似的系统,并且这些段根据权限分开。

Code has execute permission. 代码具有执行权限。 The other segments don't. 其他部分没有。 In a Windows application, you can't just put some native code on the stack and execute. 在Windows应用程序中,您不能只将一些本机代码放在堆栈上并执行。 Linux offers the same functionality- it's in the x86 architecture. Linux提供与x86架构相同的功能。

Data is data that's part of the result (.exe, etc) but can't be written to. 数据是结果(.exe等)的一部分但无法写入的数据。 This section is basically where literals go. 这部分基本上是文字的去处。 Only read permission in this section. 仅限本节中的读取权限。

Those two segments are part of the resulting file. 这两个段是结果文件的一部分。 Stack and Heap are runtime allocated, instead of mapped off the hard drive. 堆栈和堆是运行时分配的,而不是映射掉硬盘驱动器。

Stack is essentially one, large (1MB or so, many compilers offer a setting for it) heap allocation. 堆栈基本上是一个,大(1MB左右,许多编译器提供它的设置)堆分配。 The compiler manages it for you. 编译器会为您管理它。

Heap memory is memory that the OS returns to you through some process. 堆内存是操作系统通过某个进程返回给您的内存。 Normally, heap is a heap (the data structure) of pointers to free memory blocks and their sizes. 通常,堆是指向空闲内存块及其大小的指针的堆(数据结构)。 When you request one, it's given to you. 当您提出要求时,它会发给您。 Both read and write permissions here, but no execute. 这里都有读写权限,但没有执行权限。

There is read-only memory(ROM). 有只读存储器(ROM)。 However, this is just the Data section. 但是,这只是数据部分。 You can't alter it at runtime. 您无法在运行时更改它。 When you make a const variable, nothing special happens to it in memory. 当你创建一个const变量时,它在内存中没有任何特殊的变化。 All that happens is that the compiler will only create certain instructions on it. 所有发生的事情是编译器只会在其上创建某些指令。 That's it. 而已。 x86 has no knowledge or notion of const- it's all in the compiler. x86在编译器中没有const-it的全部知识或概念。

It's mostly OS dependant. 它主要取决于操作系统。

For windows take a look at Petzold or Richter's books. 对于Windows,请查看Petzold或Richter的书籍。 For Linux you can read the source ! 对于Linux,您可以阅读源代码!

AFAIK: 据我所知:

Stack/Heap do they use the same section of memory as they can grow independently? 堆栈/堆是否使用相同的内存部分,因为它们可以独立生长?

They can grow indipendently. 他们可以独立成长。

What is this code section? 这段代码是什么?

A read-only segment where code and const data are stored. 存储代码和const数据的只读段。

When I have a function is it a part of the stack or the code section? 当我有一个函数是它的一部分堆栈或代码部分?

The definition (code) of the function will be in the CS. 函数的定义(代码)将在CS中。 The arguments of each call are passed on the stack. 每个调用的参数都在栈上传递。

Also what is this initialized/uninitialized data segment? 这个初始化/未初始化的数据段是什么?

The data segment is where globals/static variables are stored. 数据段是存储全局/静态变量的位置。

Are there read only memory section available? 是否有只读存储器部分?

The code segment. 代码段。 I suppose some OS's might offer primitives for creating custom read-only segments. 我想一些操作系统可能会提供用于创建自定义只读段的基元。

When I have a const variable, what is actually happening is it that the compiler marks a memory section as read only or does it put into a read only memory section. 当我有一个const变量时,实际发生的是编译器将内存部分标记为只读或将其放入只读内存部分。

It goes into the CS. 它进入了CS。

Where are static data kept? 静态数据保存在哪里? Where are global data kept? 全球数据保存在哪里?

The data segment. 数据段。

I was in same dilemma when I was reading about memory layout's of C/C++. 当我阅读关于C / C ++的内存布局时,我处于同样的两难境地。 Here is the link which I followed to get the questions cleared. 这是我为了解决问题而遵循的链接。

http://www.geeksforgeeks.org/memory-layout-of-c-program/ http://www.geeksforgeeks.org/memory-layout-of-c-program/

The link's main illustration is added here: 此处添加了链接的主要插图:

在此输入图像描述

I hope this helps 'the one' finding answers to similar question. 我希望这有助于“那个人”找到类似问题的答案。

(Note: The following applies to Linux) (注意:以下内容适用于Linux)

The stack and heap of a process both exist in the "same" part of a process's memory. 进程的堆栈和堆都存在于进程内存的“相同”部分。 The stack and heap grow towards each other (initially, when the process is started, the stack occupies the entire area that can be occupied by the combination of the stack and the heap; each memory allocation (malloc/free/new/delete) can push the boundary between the stack and the heap either up or down). 堆栈和堆相互增长(最初,当进程启动时,堆栈占用堆栈和堆的组合可占用的整个区域;每个内存分配(malloc / free / new / delete)都可以向上或向下推动堆栈和堆之间的边界)。 The BSS section, also located on the same OS-allocated process space, is in its own section and contains global variables. BSS部分也位于相同的OS分配的进程空间中,它位于自己的部分中并包含全局变量。 Read-only data resides in the rodata section and contains such things as string literals. 只读数据驻留在rodata部分,包含字符串文字等内容。 For example, if your code has the line: 例如,如果您的代码包含以下行:

char tmpStr[] = "hello";

Then, the portion of the source code containing "hello" will reside in the rodata section. 然后,包含“hello”的源代码部分将驻留在rodata部分中。

A good, thorough book on this is Randall E. Bryant's Computer Systems. Randall E. Bryant的计算机系统是一本很好的,完整的书。

As an addendum to the answers, here is a quote from GotW that classifies some major memory areas (note the difference between free-store, which is what I would usually refer to as the heap, and the actual heap, which is the part managed through malloc/free). 作为答案的补充,这里引用了GotW对一些主要内存区域的分类(请注意免费存储区域之间的差异,这就是我通常称之为堆的区域)和实际堆栈,这是管理的部分通过malloc / free)。 The article is a bit old so I don't know if it applies to modern C++; 这篇文章有点旧,所以我不知道它是否适用于现代C ++; so far I haven't found a direct contradiction. 到目前为止,我还没有找到直接的矛盾。

Const Data The const data area stores string literals and other data whose values are known at compile time. Const数据const数据区存储字符串文字和其值,这些数据的值在编译时是已知的。 No objects of class type can exist in this area. 此区域中不存在类类型的对象。 All data in this area is available during the entire lifetime of the program. 该区域中的所有数据均可在程序的整个生命周期内使用。 Further, all of this data is read-only, and the results of trying to modify it are undefined. 此外,所有这些数据都是只读的,尝试修改它的结果是不确定的。 This is in part because even the underlying storage format is subject to arbitrary optimization by the implementation. 这部分是因为即使是底层存储格式也会受到实现的任意优化。 For example, a particular compiler may store string literals in overlapping objects if it wants to. 例如,如果需要,特定编译器可以将字符串文字存储在重叠对象中。

Stack The stack stores automatic variables. 堆栈堆栈存储自动变量。 Typically allocation is much faster than for dynamic storage (heap or free store) because a memory allocation involves only pointer increment rather than more complex management. 通常,分配比动态存储(堆或自由存储)快得多,因为内存分配仅涉及指针增量而不是更复杂的管理。 Objects are constructed immediately after memory is allocated and destroyed immediately before memory is deallocated, so there is no opportunity for programmers to directly manipulate allocated but uninitialized stack space (barring willful tampering using explicit dtors and placement new). 在内存被释放之前立即分配和销毁内存后立即构造对象,因此程序员没有机会直接操作已分配但未初始化的堆栈空间(禁止使用显式dtors和placement new)进行故意篡改。

Free Store The free store is one of the two dynamic memory areas, allocated/freed by new/delete. 免费商店免费商店是两个动态内存区域之一,由new / delete分配/释放。 Object lifetime can be less than the time the storage is allocated; 对象生存期可以小于分配存储的时间; that is, free store objects can have memory allocated without being immediately initialized, and can be destroyed without the memory being immediately deallocated. 也就是说,免费存储对象可以在不立即初始化的情况下分配内存,并且可以在不立即释放内存的情况下销毁它们。 During the period when the storage is allocated but outside the object's lifetime, the storage may be accessed and manipulated through a void* but none of the proto-object's nonstatic members or member functions may be accessed, have their addresses taken, or be otherwise manipulated. 在分配存储但在对象的生命周期之外的期间,可以通过void *访问和操纵存储,但是可以访问原始对象的非静态成员或成员函数,获取其地址或以其他方式操作。

Heap The heap is the other dynamic memory area, allocated/freed by malloc/free and their variants. 堆是另一个动态内存区域,由malloc / free及其变体分配/释放。 Note that while the default global new and delete might be implemented in terms of malloc and free by a particular compiler, the heap is not the same as free store and memory allocated in one area cannot be safely deallocated in the other. 请注意,虽然默认的全局new和delete可能由malloc实现并且由特定编译器释放,但堆与free store不同,并且在一个区域中分配的内存无法在另一个区域中安全地释放。 Memory allocated from the heap can be used for objects of class type by placement-new construction and explicit destruction. 从堆分配的内存可以通过放置 - 新构造和显式销毁用于类类型的对象。 If so used, the notes about free store object lifetime apply similarly here. 如果这样使用,关于免费商店对象生存期的注释在此类似地适用。

Global/Static Global or static variables and objects have their storage allocated at program startup, but may not be initialized until after the program has begun executing. 全局/静态全局或静态变量和对象在程序启动时分配其存储,但在程序开始执行之前可能不会初始化。 For instance, a static variable in a function is initialized only the first time program execution passes through its definition. 例如,函数中的静态变量仅在程序执行第一次通过其定义时初始化。 The order of initialization of global variables across translation units is not defined, and special care is needed to manage dependencies between global objects (including class statics). 未定义跨翻译单元的全局变量的初始化顺序,并且需要特别注意管理全局对象(包括类静态)之间的依赖关系。 As always, uninitialized proto- objects' storage may be accessed and manipulated through a void* but no nonstatic members or member functions may be used or referenced outside the object's actual lifetime. 与往常一样,未初始化的原始对象的存储可以通过void *进行访问和操作,但不能在对象的实际生命周期之外使用或引用非静态成员或成员函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM