【转】程序的内存分配之堆和栈的区别

[东拼西凑]STM32单片机启动流程及RAM和Flash的配置关系和堆栈溢出现象 开头的话: 之前一直用现成的LED工程demo,改改就上,也没细究。直到做MQTT移植的时候,发现malloc始终出错,开始找问题,于是写下本文。(前前后后摘抄、参考、改进本文,侵删) 一、STM32上电启动 BOOT1 BOOT0 启动方式 X 0 从STM32内置flash启动,JTAG或者SWD固化程序位置 1 1 从STM32内置SRAM启动,由于SRAM没有程序存储能... 阅读详情

文章来源:微wx笑 链接


堆栈概述

在计算机领域,堆栈是一个不容忽视的概念,堆栈是两种数据结构。堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。在单片机应用中,堆栈是个特殊的存储区,主要功能是暂时存放数据和地址,通常用来保护断点和现场。

要点:
堆,优先队列(priority queue);普通的队列是一种先进先出的数据结构(FIFO—First-In/First-Out),元素在队列尾追加,而从队列头删除,(例如:乘车排队,先来的排在前面先上车,后来的就要排的后面后上车; 哎,哎,你怎么插队呢,学没学过队列);在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先取出。优先队列具有最高级先出 (largest-in,first-out)的行为特征。

栈,先进后出(FILO—First-In/Last-Out)(例如:超市排队结账,大一点的超市收银台都是一段狭长的过道,本来下一个是你了,突然这个收银台说不结了,OK,栈形成了,排在前面的要后出去了)。

一、程序的内存分配

1、一个由C/C++编译的程序占用的内存分为以下几个部分

1)、栈区(stack)

由编译器自动分配释放,存放函数的参数值,局部变量的值等。其
操作方式类似于数据结构中的栈。

2)、堆区(heap)

一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回
收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

3)、全局区(静态区)(static)

全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 程序结束后由系统释放。

4)、文字常量区

常量字符串就是放在这里的,程序结束后由系统释放 。

5)、程序代码区

存放函数体的二进制代码。

2、变量的存储方式

这里写图片描述
  首先,定义静态变量时如果没有初始化编译器会自动初始化为0.。接下来,如果是使用常量表达式初始化了变量,则编译器仅根据文件内容(包括被包含的头文件)就可以计算表达式,编译器将执行常量表达式初始化。必要时,编译器将执行简单计算。如果没有足够的信息,变量将被动态初始化。请看一下代码:

int global_1=1000;//静态变量外部链接性常量表达式初始化
int global_2;//静态变量外部链接性零初始化
static int one_file_1=1000;//静态变量内部链接性常量表达式初始化
static int one_file_2;//静态变量内部链接性零初始化
int main()
{
static int count_1=1000;//静态变量无链接性常量表达式初始化
static int count_2;//静态变量无链接性零初始化
return 0;
}

  所有的静态持续变量都有下述初始化特征:未被初始化的静态变量的所有位都被设为0。这种变量被称为零初始化。以上代码说明关键字static的两种用法,但含义有些不同:用于局部声明,以指出变量是无链接性的静态变量时,static表示的是存储持续性;而用于代码块外声明时,static表示内部链接性,而变量已经是静态持续性了。有人称之为关键字重载,即关键字的含义取决于上下文。

二、C/C++堆和栈的区别

  1. 管理方式不同
    栈,由编译器自动管理,无需程序员手工控制;堆:产生和释放由程序员控制。

  2. 空间大小不同
    栈的空间有限;堆内存可以达到4G,。

  3. 能否产生碎片不同
    栈不会产生碎片,因为栈是种先进后出的队列。堆则容易产生碎片,多次的new/delete
    会造成内存的不连续,从而造成大量的碎片。

  4. 生长方向不同
    堆的生长方式是向上的,栈是向下的。

  5. 分配方式不同
    堆是动态分配的。栈可以是静态分配和动态分配两种,但是栈的动态分配由编译器释放。

  6. 缓存级别不同:
    1)、栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放;
    2)、堆是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。

  7. 分配效率不同
    栈是机器系统提供的数据结构,计算机底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令。堆则是由C/C++函数库提供,库函数会按照一定的算法在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。
    堆和栈相比,由于大量new/delete的使用,容易造成大量的内存碎片;由于没有专门的系统支持,效率很低;由于可能引发用户态和核心态的切换,内存的申请,代价变得更加昂贵。所以栈在程序中是应用最广泛的,就算是函数的调用也利用栈去完成,函数调用过程中的参数,返回地址,EBP和局部变量都采用栈的方式存放。所以,我们推荐大家 尽量用栈,而不是用堆。
    栈和堆相比不是那么灵活,有时候分配大量的内存空间,还是用堆好一些。
    无论是堆还是栈,都要防止越界现象的发生。

例子程序

//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   =   (char   *)malloc(10);    
  p2   =   (char   *)malloc(20);    
  分配得来得10和20字节的区域就在堆区。    
  strcpy(p1,   "123456");   123456/0放在常量区,编译器可能会将它与p3所指向的"123456"  
  优化成一个地方。    
  } 

三、java堆和栈的区别(未看,忽略)

  1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。
  2. 与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。
  3. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。
    但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据在多个线程或者多个栈之间是不可以共享的,但是在栈内部多个值相等的变量是可以指向一个地址的,详见第3点。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

  4. Java中的数据类型有两种。
    一种是基本类型(primitivetypes), 共有8种,即int,short, long, byte, float, double, boolean, char(注意,并没有string的基本类型)。这种类型的定义是通过诸如int a= 3; long b = 255L;的形式来定义的,称为自动变量。值得注意的是,自动变量存的是字面值,不是类的实例,即不是类的引用,这里并没有类的存在。如int a= 3; 这里的a是一个指向int类型的引用,指向3这个字面值。这些字面值的数据,由于大小可知,生存期可知(这些字面值固定定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存在于栈中。
    另外,栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:
    int a=3;
    int b=3;
    编译器先处理int a= 3;首先它会在栈中创建一个变量为a的内存空间,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b= 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。
    特别注意的是,这种字面值的引用与类对象的引用不同。假定两个类对象的引用同时指向一个对象,如果一个对象引用变量修改了这个对象的内部状态,那么另一个对象引用变量也即刻反映出这个变化。相反,通过字面值的引用来修改其值,不会导致另一个指向此字面值的引用的值也跟着改变的情况。如上例,我们定义完a与b的值后,再令a=4;那么,b不会等于4,还是等于3。在编译器内部,遇到a=4;时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。
    另一种是包装类数据,【如Integer,String, Double等将相应的基本数据类型包装起来的类。这些类数据全部存在于【堆】中】,Java用new()语句来显示地告诉编译器,在运行时才根据需要动态创建,因此比较灵活,但缺点是要占用更多的时间。 4.String是一个特殊的包装类数据。即可以用String str = new String(“abc”);的形式来创建,也可以用Stringstr = “abc”;的形式来创建(作为对比,在JDK 5.0之前,你从未见过Integer i = 3;的表达式,因为类与字面值是不能通用的,除了String。而在JDK5.0中,这种表达式是可以的!因为编译器在后台进行Integer i = new Integer(3)的转换)。前者是规范的类的创建过程,即在Java中,一切都是对象,而对象是类的实例,全部通过new()的形式来创建。Java中的有些类,如DateFormat类,可以通过该类的getInstance()方法来返回一个新创建的类,似乎违反了此原则。其实不然。该类运用了单例模式来返回类的实例,只不过这个实例是在该类内部通过new()来创建的,而getInstance()向外部隐藏了此细节。那为什么在String str = “abc”;中,并没有通过new()来创建实例,是不是违反了上述原则?其实没有。

  5. 关于String str = “abc”的内部工作。
    Java内部将此语句转化为以下几个步骤:【String str = “abc”,String str不要连着】
    (1)先定义一个名为str的对String类的对象引用变量:String str;
    (2)【在【栈】中查找有没有存放值为”abc”的地址,如果没有,则开辟一个存放字面值为”abc”的地址,接着创建一个新的String类的对象o,并将o的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对象o。如果已经有了值为”abc”的地址,则查找对象o,并返回o的地址。】【上文说数据时存放在堆中,此文说数据存放在栈中】[因为此处不是通过new()创建的啊]
    (3)将str指向对象o的地址。
    值得注意的是,一般String类中字符串值都是直接存值的。但像String str = “abc”;这种场合下,其字符串值却是保存了一个指向存在栈中数据的引用!
    为了更好地说明这个问题,我们可以通过以下的几个代码进行验证。
    String str1=”abc”;
    String str2=”abc”;
    System.out.println(str1==str2);//true
    注意,我们这里并不用str1.equals(str2);的方式,因为这将比较两个字符串的值是否相等。==号,根据JDK的说明,只有在两个引用都指向了同一个对象时才返回真值。而我们在这里要看的是,str1与str2是否都指向了同一个对象。
      结果说明,JVM创建了两个引用str1和str2,但只创建了一个对象,而且两个引用都指向了这个对象。
    我们再来更进一步,将以上代码改成:
    String str1=”abc”;
    String str2=”abc”;
    str1=”bcd”;
    System.out.println(str1+”,”+str2);//bcd,abc
    System.out.println(str1==str2);//false
    这就是说,赋值的变化导致了类对象引用的变化,str1指向了另外一个新对象!而str2仍旧指向原来的对象。上例中,当我们将str1的值改为”bcd”时,JVM发现在栈中没有存放该值的地址,便开辟了这个地址,并创建了一个新的对象,其字符串的值指向这个地址。
    事实上,String类被设计成为不可改变(immutable)的类。如果你要改变其值,可以,但JVM在运行时根据新值悄悄创建了一个新对象,然后将这个对象的地址返回给原来类的引用。这个创建过程虽说是完全自动进行的,但它毕竟占用了更多的时间。在对时间要求比较敏感的环境中,会带有一定的不良影响。
    再修改原来代码:
    String str1=”abc”;
    String str2=”abc”;
    str1=”bcd”;
    String str3=str1;
    System.out.println(str3);//bcd
    String str4=”bcd”;
    System.out.println(str1==str4);//true
    我们再接着看以下的代码。
    String str1 = new String(“abc”);
      String str2 = “abc”;
      System.out.println(str1==str2); //false
      String str1 = “abc”;
      String str2 = new String(“abc”);
      System.out.println(str1==str2); //false
    创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象。
    以上两段代码说明,只要是用new()来新建对象的,都会在堆中创建,而且其字符串是单独存值的,即使与栈中的数据相同,也不会与栈中的数据共享。

  6. 数据类型包装类的值不可修改。
    不仅仅是String类的值不可修改,所有的数据类型包装类都不能更改其内部的值。

  7. 结论与建议:
    (1)我们在使用诸如String str = “abc”;的格式定义类时,总是想当然地认为,我们创建了String类的对象str。担心陷阱!对象可能并没有被创建!唯一可以肯定的是,指向String类的引用被创建了。至于这个引用到底是否指向了一个新的对象,必须根据上下文来考虑,除非你通过new()方法来显要地创建一个新的对象。因此,更为准确的说法是,我们创建了一个指向String类的对象的引用变量str,这个对象引用变量指向了某个值为”abc”的String类。清醒地认识到这一点对排除程序中难以发现的bug是很有帮助的。
    (2)使用String str = “abc”;的方式,可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于Stringstr = new String(“abc”);的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。这个思想应该是享元模式的思想,但JDK的内部在这里实现是否应用了这个模式,不得而知。
    (3)当比较包装类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==。
    (4)由于String类的immutable性质,当String变量需要经常变换其值时,应该考虑使用StringBuffer类,以提高程序效率

四、堆和栈的理论知识

1、申请方式
stack:
由系统自动分配。 例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间
heap:
需要程序员自己申请,并指明大小,在c中malloc函数
如p1 = (char *)malloc(10);
在C++中用new运算符
如p2 = new char[10];
但是注意p1、p2本身是在栈中的。

2、申请后系统的响应
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。
另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。

3、申请大小的限制
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

4、申请效率的比较:
栈由系统自动分配,速度较快。但程序员是无法控制的。
堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.
另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是
直接在进程的地址空间中保留一块内存,虽然用起来最不方便。但是速度快,也最灵活。

5、堆和栈中的存储内容
栈: 在函数调用时,首先进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址;然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的(为什么是由右往左入栈的?),然后是函数中的局部变量。注意静态变量是不入栈的(存放在静态区)。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容由程序员安排。

6、存取效率的比较

char s1[] = “aaaaaaaaaaaaaaa”; 
char *s2 = “bbbbbbbbbbbbbbbbb”; 

aaaaaaaaaaa是在运行时刻赋值的;
而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
比如:

void main() 
{ 
char a = 1; 
char c[] = “1234567890”; 
char *p =”1234567890”; 
a = c[1]; 
a = p[1]; 
return; 
} 

对应的汇编代码

10: a = c[1]; 
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh] 
0040106A 88 4D FC mov byte ptr [ebp-4],cl 
11: a = p[1]; 
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h] 
00401070 8A 42 01 mov al,byte ptr [edx+1] 
00401073 88 45 FC mov byte ptr [ebp-4],al 

第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,再根据edx读取字符,显然慢了。

7、小结:
堆和栈的区别可以用如下的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。


~完~

工作:三菱PLC与伺服之CC-Link IE Field Network通讯应用 CC-LINK-IE 阅读详情

相关推荐

真双口RAM---Quartus与Vivado开发环境区别对比

2、写和写冲突:表示两个端口写使能同时有效且写地址相同,此时需要关断一个写,把两个写端口都需要更新的值处理到一个写端口上面,任何的DP RAM 都不支持写和写冲突。以上述直方图统计使用为例,博主在仿真过程中发现,vivado真双口RAM--B端口读写延迟2个clk;1、读和写冲突:如果读和写同时有效,且读和写是同一个地址时,发生RAM读写冲突,此时会把最新的写数据直接赋给读数据,称为写穿通到读。

weixin_54470733的博客 3583

栈(stack)与堆(heap)

1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享,详见第3点。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收

思勤专栏 775

避坑指南:vue-print-nb打印隐藏元素与空白页的那些事儿

本文深入解析了使用vue-print-nb插件时,打印出现空白页及隐藏元素问题的根本原因与解决方案。核心在于理解浏览器打印原理,并通过CSS媒体查询精准控制样式。文章提供了从重置根元素高度、处理隐藏元素到控制分页的完整避坑指南,帮助开发者彻底解决打印样式难题。

weixin_29008691的博客 437

堆栈和内存的关系

五大内存分区    在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。    栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。    堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,

浩瀚星空,法力无边;其大无外,其小无内。 2022

Vc出现不能连接到一个或多个 vCenter server 系统:http://vcenter-vx.utibet.edu.cn:443/sdk

问题描述: 解决办法: esxi6.7的bug 第一种通过升级系统来解决问题 第二种是通过删除数据来解决 第一步:进入到esxi的shell 第二步查看其中的服务开启状态 第二步 df -h 第三步 /opt/vmware/vpostgres/current/bin/psql -d VCDB -U postgres 第四步 SELECT nspname || '.' || relname AS "relation", pg_size_pretty(pg_total_relation_size(C.oi

m0_49328536的博客 9901

统信UOS系统盘空间不足?5分钟搞定扩容的图形化解决方案

本文提供统信UOS系统盘空间不足的图形化扩容解决方案,使用GParted分区编辑器在不丢失数据的情况下快速完成扩容。详细步骤包括准备工作、空间调整和执行验证,适合技术用户快速解决问题。

d6e7f8的博客 959

栈、堆、缓存、内存之间的联系

先说栈和堆 栈和堆都是放在内存里的,没错就是RAM,通常所说的内存条! 因为程序运行就是在运行在内存里的! 栈和堆有什么区别? 栈:栈的大小是静态的,是编译时就知道的,比如数组的大小,每个程序允许申请的栈大小是有上限的,数组申请过大,会导致栈溢出! 堆:堆的大小是动态的,程序运行是动态申请的,不固定,比如new对象的个数和大小!需要自己手动释放,不然会导致内存泄漏! 缓存: 分为两种:程序缓存和CPU缓存 程序缓存:就是所说的缓冲区!栈和堆都属于程序缓存!让数据保存在内存中,加快程序计算效率

qq_37061368的博客 5530

论文阅读—Square Attack: a query-efficient black-box adversarial attack via random search

论文阅读—Square Attack: a query-efficient black-box adversarial attack via random search 发表位置 ECCV 2020 摘要 作者提出了一种基于得分的黑盒Square attack,该模型不依赖于模型的局部梯度信息,因此可以绕过梯度隐藏防御攻击。Square Attack是一种随机搜索方法,它在随机位置选择局部的方形更新,使得每次迭代时扰动近似位于可行集的边界。 背景 当涉及到对安全至关重要的机器学习应用时,对抗性的例子尤其值得

yayayamaomaoya的博客 2494

栈、堆和静态区、内存、flash、RAM的概念

对于程序员,一般来说,我们可以简单的理解为内存分为三个部分:静态区,栈,堆。很多书没有把把堆和栈解释清楚,导致初学者总是分不清楚。其实堆栈就是栈,而不是 堆。堆的英文是heap;栈的英文是stack,也翻译为堆栈。堆和栈都有自己的特性,这里先不做讨论。再打个比方:一层教学楼,可能有外语教室,允许外语系学生和老师进入; 还可能有数学教师,允许数学系学生和老师进入;还可能有校长办公室,允许校长进入

行者 1万+

Vue3 - 实现集成配置百度语音识别转文字,长按或开启录音并将录音文件实时转换为文字,上传音频文件利用百度语音识别API转换为文本并展示(vue3百度智能云API实现上传录音文件并转换成文字案例)

vue3对接百度智能云语音识别,vue3 h5移动端网页中实现语音识别,百度语音识别录音转文字_百度智能云,vue3如何使用百度语音识别,如何将语音转文字,使用vue3实现录音并将录音转换为文字,vue3如何实现语音输入功能功能,vue3集成百度智能云API实现录音转文字详细教程完整示例代码demo,VUE3使用百度语音识别语音转文字,vue调用百度语音识别,vue3百度语音识别文字并展示功能,vue3免费语音转文本api,百度语音识别申请配置教程,Vue3项目配置自定义界面百度语音识别转文字和原生使用方式

🏆 前端领域优质创作者 2728

YOLOv11改进 | 主干/Backbone篇 | 华为最新目标检测网络VanillaNet(适配yolov11的N、S、M、L、X)

本文给大家来的改进机制是华为最新VanillaNet网络VanillaNet是一种注重极简主义和效率的神经网络架构。它的设计简单,层数较少,避免了像深度架构和自注意力这样的复杂操作(需要注意的是该网络结构的通道数会被放大,GFLOPs的量会很高)。我将其替换整个YOLOv10的Backbone,在一些大目标和小目标检测上均有涨点,效果比上一篇RepViT的效果要好。

Snu77的博客 2587

C语言程序编译的内存分配,堆与栈的区别[转]

C语言程序编译的内存分配: 1.栈区(stack)--编译器自动分配释放,主要存放函数的参数值,局部变量值等; 2.堆区(heap)--由程序员分配释放; 3.全局区或静态区--存放全局变量和静态变量;程序结束时由系统释放,分为全局初始化区和全局未初始化区; 4.字符常量区--常量字符串放与此,程序结束时由系统释放; 5.程序代码区 例: //main.c int ...

weixin_30878361的博客 96

Open3D 点云数学形态学滤波(Python版本)

Open3D 点云数学形态学滤波(Python版本)

dayuhaitang1的博客 1397

【转】堆和栈的区别

转自csdn接近46万阅读量的文章:https://blog.youkuaiyun.com/hairetz/article/details/4141043 参加企鹅面试时出现过这道题 一、预备知识—程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其 操作方式类似于数据结...

weixin_30556161的博客 63

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

栈和堆的区别

一、程序的内存分配方式不同 栈区(stack):编译器自动分配释放,存放函数的参数值,局部变量的值等,其操作方式类似于数据结构的栈。 堆区(heap):一般是由程序员分配释放,若程序员不释放的话,程序结束时可能由OS回收,值得注意的是他与数据结构的堆是两回事,分配方式倒是类似于数据结构的链表。 二、申请方式不同 stack 由系统自动分配,heap 需要程序员自己申请。 C 中用函数 ma...

Hustle Everyday 6万+

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

程序的内存分配之堆和栈的区别

堆栈概述  在计算机领域,堆栈是一个不容忽视的概念,堆栈是两种数据结构。堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。在单片机应用中,堆栈是个特殊的存储区,主要功能是暂时存放数据和地址,通常用来保护断点和现场。要点: 堆,优先队列(priority queue);普通的队列是一种先进先出的数据结构(FIFO—First-In/First-Out),元

无知人生,记录点滴 1万+

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

浅谈内存分配方式以及堆和栈的区别(很清楚)

对于一个程序要运行,涉及到的内存分配是一个首要问题,这里简单说一下一个简单的程序运行所涉及到的内存分配方式。另外,在数据结构中存在堆和栈的概念,栈是一种先进后出的数据结构,堆则是一种排序方式,而在内存分配中也存在堆(heap)和栈(stack)的概念,与数据结构中的概念不同,这里简单说明在内存分配中的堆栈之间的不同。 一、内存分配方式 1、全局变量和静态变量(static变量),是由编译器自动

shanchangyi的博客 1万+

堆区和栈区的区别

堆和栈的区别 一、预备知识—程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。 3、全局区(静态

ztf_dafen的博客 8538

浅析栈区和堆区内存分配的区别

转载自:https://www.jb51.net/article/40513.htm 以下是对栈区和堆区内存分配的区别进行了详细的分析介绍,需要的朋友可以过来参考下 一直以来总是对这个问题的认识比较朦胧,我相信很多朋友也是这样的,总是听到内存一会在栈上分配,一会又在堆上分配,那么它们之间到底是怎么的区别呢?为了说明这个问题,我们先来看一下内存内部的组织情况. 从上图可知,程序占用的内存被...

寂蝶难双,窃窃思羽. 1664

内存分配——堆和栈的区别

1、数据结构的栈和堆     堆栈,实际上堆栈是两种数据结构:堆和栈。     堆和栈都是把一些数据项按序排列的数据结构。 2、内存分配中的栈和堆     这里有必要把内存分配:一般情况下程序存放在Rom或Flash中,运行时需要拷到内存中执行,内存会分别存储不同的信息,如下图(数据在内存中的存储图示)所示: 0xc0000000 内核虚拟内存      ——有内核使用

DBA@Robin 2998

程序的内存分配 堆和栈

堆和栈的区别 一、预备知识—程序的内存分配    一个由c/C++编译的程序占用的内存分为以下几个部分    1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。    2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。

jiang_chuang的专栏 749

堆和栈的区别?堆和栈的内存分配速度?

栈:快速,自动管理,用于局部变量和函数调用,但受限于栈大小。堆:灵活,手动管理,用于动态内存分配,但可能导致内存泄漏和碎片化。两者的选择通常取决于内存使用的具体需求以及程序的设计结构。

m0_48022770的博客 1092

堆和栈最通俗的_堆和栈的区别详解

前言:在程序设计的时候、堆栈总是不可避免的会接触到、而对于堆和栈他们的区别、在程序运行时各自的作用,如何利用堆栈提高运行效率等很多人都还了解的不够,今天google了很多文章,所以在这里作个完善总结,希望能给有心人些帮助。有不足的地方还希望能指出。栈是随函数被调用时分配的空间栈上分配的空间是临时的,在函数退出后将被系统释放,不会造成内存泄露,不得用delete或free操作,因为栈的空间小所以在栈...

weixin_29189003的博客 950

堆 栈 程序 内存分配 详解

 堆和栈的区别一、预备知识—程序的内存分配    一个由c/C++编译的程序占用的内存分为以下几个部分    1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。    2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。 

SearchLife的专栏 1705
上一篇: 【转】程序员如何经营个人品牌
下一篇: 【转】你应该知道的 RPC 原理
wangeshen
博客等级 码龄19年 0粉丝 1原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值