什么存储在堆上,什么存储在堆上?
任何人都可以用C,C ++和Java清楚地解释一下。什么都在堆栈上,什么都在堆上以及何时分配。
我所知道的,
每个函数调用的所有局部变量(无论是基元,指针还是引用变量)都在新的堆栈框架上。
使用new或malloc创建的所有内容都会进入堆。
我对几件事感到困惑。
是在堆上创建的对象成员的引用/基元是否也存储在堆上?
以及在每个框架中递归创建的方法的那些本地成员呢?它们都在堆栈上吗?如果是,那么在运行时是否分配了堆栈内存?同样对于文字,它们是否属于代码段?以及C中的全局变量,C
++ / Java中的static和C中的static。
回答:
以下是任何程序在装入内存后的基本结构。
+--------------------------+ | |
| command line |
| arguments |
| (argc and argv[]) |
| |
+--------------------------+
| Stack |
| (grows-downwards) |
| |
| |
| |
| F R E E |
| S P A C E |
| |
| |
| |
| |
| (grows upwards) Heap |
+--------------------------+
| |
| Initialized data |
| segment |
| |
+--------------------------+
| |
| Initialized to |
| Zero (BSS) |
| |
+--------------------------+
| |
| Program Code |
| |
+--------------------------+
需要注意的几点:
- 数据段
- 初始化的数据段(由程序员初始化为显式初始化程序)
- 未初始化的数据段(已初始化为零数据段-BSS [以符号开头的块])
- 代码段
- 堆和堆区域
数据段包含由包含初始化值的用户显式初始化的全局和静态数据。
数据段的另一部分称为BSS(因为旧的IBM系统将该段初始化为零)。这是操作系统将内存块初始化为零的内存部分。这就是未初始化的全局数据和静态如何将默认值设为零。该区域是固定的,并且具有静态大小。
基于显式初始化,数据区域被分为两个区域,因为要初始化的变量可以被一对一地初始化。但是,未初始化的变量不需要用0的一对一显式初始化。取而代之的是,初始化变量的工作留给操作系统。批量初始化可以大大减少加载可执行文件所需的时间。
大多数情况下,数据段的布局在底层操作系统的控制之下,但仍有一些加载程序将部分控制权交给用户。该信息在诸如嵌入式系统的应用中可能是有用的。
可以使用代码中的指针来寻址和访问该区域。自动变量在每次需要它们时都具有初始化变量的开销,并且需要代码来进行该初始化。但是,数据区域中的变量没有这样的运行时过载,因为初始化仅执行一次,并且在加载时也进行一次。
程序代码是可执行代码可用于执行的代码区域。该区域的大小也固定。只能通过函数指针访问,不能通过其他数据指针访问。此处要注意的另一个重要信息是,系统可能将此区域视为只读存储区域,并且任何在该区域中进行写入的尝试都将导致未定义的行为。
常量字符串可以放置在代码或数据区域中,具体取决于实现方式。
尝试写入代码区域会导致未定义的行为。例如(下面我仅给出C
一些示例),以下代码可能会导致运行时错误,甚至使系统崩溃。
int main(){
static int i;
strcpy((char *)main,"something");
printf("%s",main);
if(i++==0)
main();
}
为了执行,程序使用了两个主要部分,即堆栈和堆。堆栈帧是在堆栈中创建的,用于功能;在堆栈中创建的是用于动态内存分配。堆栈和堆是未初始化的区域。因此,存储器中发生的任何事情都将成为在该空间中创建的对象的初始(垃圾)值。
让我们看一个示例程序,以显示哪些变量存储在哪里,
int initToZero1;static float initToZero2;
FILE * initToZero3;
// all are stored in initialized to zero segment(BSS)
double intitialized1 = 20.0;
// stored in initialized data segment
int main()
{
size_t (*fp)(const char *) = strlen;
// fp is an auto variable that is allocated in stack
// but it points to code area where code of strlen() is stored
char *dynamic = (char *)malloc(100);
// dynamic memory allocation, done in heap
int stringLength;
// this is an auto variable that is allocated in stack
static int initToZero4;
// stored in BSS
static int initialized2 = 10;
// stored in initialized data segment
strcpy(dynamic,”something”);
// function call, uses stack
stringLength = fp(dynamic);
// again a function call
}
还是考虑一个更复杂的例子,
// command line arguments may be stored in a separate area int main(int numOfArgs, char *arguments[])
{
static int i;
// stored in BSS
int (*fp)(int,char **) = main;
// points to code segment
static char *str[] = {"thisFileName","arg1", "arg2",0};
// stored in initialized data segment
while(*arguments)
printf("\n %s",*arguments++);
if(!i++)
fp(3,str);
}
希望这可以帮助!
以上是 什么存储在堆上,什么存储在堆上? 的全部内容, 来源链接: utcz.com/qa/428218.html