b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

内存和堆内存的区别(一个笔试题的一部分)

电脑杂谈  发布时间:2021-05-07 09:02:39  来源:网络整理

堆栈内存和堆内存之间的差异(书面测试的一部分)

书面测试标题:请解释一下堆栈存储器和堆存储器之间的区别,请分析以下代码操作是否有问题,如果有问题,请更正它。

char * GetMemory(void)

{

char p [] =“ Hello world”;

返回p;

}

void main(void)

{

char * str = GetMemory();

printf(str);

}

首先看第一个问题:堆栈内存和堆内存之间的区别

程序存储器分配

堆栈:它由编译器自动分配和释放,存储函数参数,局部变量,临时变量,函数返回地址等;

堆(heap):通常,程序员分配并释放它。如果未手动发布,则可能会在程序结束时由操作系统自动发布(?这可能适用于具有回收机制的Java之类的语言。对于c / c ++,则必须手动发布打开的堆内存),稍有疏忽会导致内存泄漏。

2.应用后的系统响应

堆栈:只要堆栈的剩余空间大于请求的空间,系统就会为程序提供内存,否则将报告异常以指示堆栈溢出。

堆:在记录可用内存地址的链表中找到一个空间大于所请求空间的堆节点,然后从该空闲节点链表中删除该节点,并将该节点的空间分配给程序。此外,对于大多数系统,分配空间的大小将记录在该存储空间的第一个地址,以便代码中的删除操作可以正确释放该存储空间。系统将重新释放链表中的冗余部分。

3、申请尺寸限制

堆栈:在Windows中,堆栈是一个扩展到较低地址的数据结构,并且是内存的连续区域。这句话表示系统顶部已定义了堆栈顶部的地址和堆栈的最大容量。在WINDOWS下,堆栈的大小为2M(有人说是1M,简而言之,它是在编译时确定的常数)。当请求的空间超过堆栈的剩余空间时,将提示溢出。因此,堆栈中可用的空间较小。

堆:堆是一种扩展到高地址的数据结构,并且是一个不连续的内存区域。这是因为系统使用链表存储自然不连续的空闲内存地址,并且链表的遍历方向是从低地址到高地址。堆的大小受计算机系统中有效虚拟内存的限制。可以看出,堆获得的空间更加灵活,更大。

4、分配效率

堆栈:由系统自动分配,速度更快。但是程序员无法控制它。

堆:new分配的内存通常较慢并且容易出现内存碎片,但是使用起来最方便。此外,在WINDOWS下,最好的方法是使用VirtualAlloc分配内存,而不是在堆中,也不是在堆栈中,尽管使用起来最不方便,但堆栈直接在进程的地址空间中保留快速内存。但这是最快,最灵活的

5、存储内容

堆栈:在堆栈中,第一个要压入堆栈的是主函数的下一条指令的地址,然后是该函数的参数。在大多数编译器中,参数从右到左被压入堆栈,然后将函数Local variable压入堆栈。请注意,静态变量不会被压入堆栈。弹出的顺序正好相反。

堆:通常,一个字节用于在堆的开头存储堆的大小,具体内容由程序员安排。

根据《 C ++内存管理技术内幕》一书,在C ++中,内存分为5个区域,分别是堆,堆栈,可用存储区,全局/静态存储区和恒定存储区。

a)堆栈:内存在需要时由编译器自动分配和释放。通常用于存储局部变量和函数参数。 (为运行该功能而分配的局部变量,函数参数,返回地址等存储在堆栈区域中)。堆栈操作分配内置在处理器的指令集中,这非常有效,但是分配的内存容量有限。

b)堆:分配了新的内存,并使用delete或delete []释放了内存。如果内存释放不正确,将导致内存泄漏。但是在程序结束时,它将由操作系统自动回收。

c)可用存储区:使用malloc进行分配,使用free进行恢复。类似于堆。

d)全局/静态存储区:全局变量和静态变量分配给同一块内存。 C语言区分初始化和未初始化,因此在C ++中不再区分。 (全局变量,静态数据和常量存储在全局数据区域中)

e)常量存储区:存储不允许修改的常量。

在某些材料中,C ++内存分配是通过这种方式定义的。可编程存储器基本上分为几个部分:静态存储区,堆区和堆栈区。它们的功能不同,因此使用方式也不同。

a)静态存储区:在编译程序时分配内存,并且该内存在程序的整个运行期间都存在。它主要存储静态数据,全局数据和常量。

b)堆栈区域:执行函数时,可以在堆栈上创建函数中局部变量的存储单元,并且在执行函数时会自动释放这些存储单元。堆栈内存分配操作内置在处理器的指令集中,虽然效率很高,但是分配的内存容量有限。

c)堆区域:也称为动态内存分配。程序运行时,请使用malloc或new来申请任何大小的内存,并且程序员负责在适当的情况下使用free或delete释放内存。动态内存的寿命可以由我们确定。如果我们不释放内存,程序将在最后释放动态内存。但是,一种好的编程习惯是:如果不再使用某个动态内存,则需要释放它,否则,我们认为发生了内存泄漏。

\

图3典型的C ++内存区域

摘要:C ++和C语言之间的内存分配有所不同,但总体上是相同的,不会影响程序分析。就C ++而言,它是5个部分还是3个部分,但是除法是不一致的。将5个部分中的c)d)e)组合为3)a)。

以下代码片段会让您感觉很清楚:

void fn()

{

int * p =新的int [5];

}

当您看到新的内容时,首先应该认为我们已经分配了一块堆内存。指针p呢?它分配了一块堆栈内存,因此这句话的含义是:指向一块堆内存的指针存储在堆栈内存中的指针p。该程序将首先确定在堆中分配的内存大小,然后调用new运算符分配内存,然后返回该内存的第一个地址并将其放在堆栈中。

注意:为简单起见,此处未释放内存,那么如何释放它呢?是删除吗?不,是的,应该是delete [] p,它告诉编译器:delete是一个数组。

// main.cpp

int a = 0;全局初始化区

char * p1;全球未初始化区域

main()

{

int b;堆栈

char s [] =“ abc”;堆栈

char * p2;堆栈

char * p3 =“ 123456”; 123456 \ 0位于常量区域,而p3位于堆栈中。

static int c = 0;全局(静态)初始化区域

p1 =(字符*)malloc(1 0);

p2 =(字符*)malloc(2 0);

分配的10和20个字节位于堆区域中。

strcpy(p1,“ 123456”); 123456 \ 0放置在常量区域中,编译器可以对其进行优化,并将p3指向的“ 123456”放在一个位置。


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shoujiruanjian/article-373653-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...