C语言堆和栈
单片机C语言 必知的数据存储与程序编写知识 附单片机应用编程知识介绍
一、五大内存分区内存分成5个区,它们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
1、栈区(StaCk):FIFo就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。
里面的变量通常是局部变量、函数参数等。
2、堆区(heap):就是那些由new分配的内存块,它们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。
如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
3、自由存储区:就是那些由malloc等分配的内存块,它和堆是十分相似的,不过它是用free 来结束自己的生命。
4、全局/静态存储区:全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
5、常量存储区:这是一块比较特殊的存储区,它们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多)code/data/stack内存主要分为代码段,数据段和堆栈。
代码段放程序代码,属于只读内存。
数据段存放全局变量,静态变量,常量等,堆里存放自己malloc或new出来的变量,其他变量就存放在栈里,堆栈之间空间是有浮动的。
数据段的内存会到程序执行完才释放。
调用函数先找到函数的入口地址,然后计算给函数的形参和临时变量在栈里分配空间,拷贝实参的副本传给形参,然后进行压栈操作,函数执行完再进行弹栈操作。
字符常量一般放在数据段,而且相同的字符常量只会存一份。
二、C语言程序的存储区域1、由C语言代码(文本文件)形成可执行程序(二进制文件),需要经过编译-汇编-连接三个阶段。
编译过程把C语言文本文件生成汇编程序,汇编过程把汇编程序形成二进制机器代码,连接过程则将各个源文件生成的二进制机器代码文件组合成一个文件。
2、C语言编写的程序经过编译-连接后,将形成一个统一文件,它由几个部分组成。
堆、栈的概念与理解
1、从数据结构层次理解,栈是一种先进后出的线性表,只要符合先进后出的原则的线性表都是栈。至于采用的存储方式(实现方式)是顺序存储(顺序栈)还是链式存储(链式栈)是没有关系的。堆则是二叉树的一种,有最大堆最小堆,排序算法中有常用的堆排序。
2、从系统层次理解,栈是系统为运行的程序分配的先进后出的存储区域。在学习bootloader时知道,在上电后初始化阶段要为各个工作模式下分配堆 栈,这里的堆栈实际上就是指stack,堆栈的说法只是因为历史的原因。在执行函数时,函数内部局部变量的存储单元可以在栈上创建(针对CISC架构而 言,RISC架构下,局部变量的存储单元是在寄存器上创建),函数执行结束时这些存储单元自动被释放。堆是系统管理的可以被程序利用的全局存储空间,动态 内存分配就是从堆上分配。
什么是堆什么是栈
一 英文名称
堆和栈是C/C++编程中经常遇到的两个基本概念。先看一下它们的英文表示:
堆――heap
栈――stack
二 从数据结构和系统两个层次理解
在具体的C/C++编程框架中,这两个概念并不是并行的。深入到汇编级进行研究就会发现,栈是机器系统提供的数据结构,而堆是由C/C++函数库提供的。这两个概念可以从数据结构和系统两个层次去理解:
具体地说,现在计算机(串行执行机制),都直接在代码层次支持栈这种数据结构。这体现在,有专门的寄存器指向栈所在的地址,有专门的机器指令完成数据入栈 出栈的操作。比如ARM指令中的stmfd和ldmfd。因为栈内存分配运算内置于处理器的指令集中,所以效率很高,但是支持的数据有限,一般是整数、指 针、浮点数等系统直接支持的数据类型,并不直接支持其他的数据结构。在CISC中,对子程序的调用就是利用栈来完成的。C/C++中的自动变量也是直接利 用栈的例子,这就是为什么当函数返回时,该函数的自动变量失效的原因(因为栈恢复了调用前的状态)。在RISC下,这些都是通过寄存器来完成的。这些留待 第二部分总结中详细阐述。
堆栈及静态数据区详解
堆、栈及静态数据区详解五大内存分区在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。
里面的变量通常是局部变量、函数参数等。
堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。
如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free 来结束自己的生命的。
全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多)明确区分堆与栈在bbs上,堆与栈的区分问题,似乎是一个永恒的话题,由此可见,初学者对此往往是混淆不清的,所以我决定拿他第一个开刀。
首先,我们举一个例子:void f() { int* p=new int[5]; }这条短短的一句话就包含了堆与栈,看到new,我们首先就应该想到,我们分配了一块堆内存,那么指针p呢?他分配的是一块栈内存,所以这句话的意思就是:在栈内存中存放了一个指向一块堆内存的指针p。
在程序会先确定在堆中分配内存的大小,然后调用operator new分配内存,然后返回这块内存的首地址,放入栈中,他在VC6下的汇编代码如下:00401028 push 14h0040102A call operator new (00401060)0040102F add esp,400401032 mov dword ptr [ebp-8],eax00401035 mov eax,dword ptr [ebp-8]00401038 mov dword ptr [ebp-4],eax这里,我们为了简单并没有释放内存,那么该怎么去释放呢?是delete p么?澳,错了,应该是delete []p,这是为了告诉编译器:我删除的是一个数组,VC6就会根据相应的Cookie 信息去进行释放内存的工作。
c堆空间和栈空间默认值
c堆空间和栈空间默认值C语言是一门广泛应用于嵌入式系统、操作系统及系统编程领域的编程语言。
它的简单易学、代码高效、性能出色及可移植性强等特点,使得它在各个领域得到了广泛的应用。
但是,一些仅在C语言中才存在的问题常常令人困扰,比如说堆空间和栈空间的默认值问题。
下面,我们就来仔细讲讲。
一、什么是堆空间和栈空间?堆空间和栈空间是程序运行时的两个不同的内存区域。
简单来说,栈空间主要用于存放局部变量、函数参数、返回地址等数据,而堆空间可以让程序员自己控制动态分配和释放内存。
同时,堆空间还可以用来存储全局变量和静态变量等。
二、堆空间和栈空间的默认值在C语言中,堆空间和栈空间的大小是有限制的。
且不说堆空间几乎是没有限制的,栈空间大小却是固定的(根据不同的编译器、操作系统有不同的限制,一般在1MB~2MB之间)。
当栈空间的大小超过限制时,会发生栈溢出的情况,程序会崩溃。
因此,在编程时,需要根据实际情况合理分配内存空间,避免出现这种情况。
对于堆空间而言,它的默认值是不确定的。
在一些编译器中,堆空间默认的大小是0,也就是说,程序员必须手动为它分配空间。
这种编译器通常是为了减少程序的运行内存的占用,提高程序的效率。
而在另一些编译器中,堆空间默认大小是非0的,但是其值也是不确定的。
在这种情况下,程序员也必须手动为堆空间分配空间。
三、堆空间和栈空间的手动分配由于堆空间和栈空间的默认值存在不确定性,因此程序员必须手动为它们分配空间。
在C语言中,通过malloc()函数和free()函数可以实现堆空间的手动分配和释放。
而栈空间的手动分配主要通过函数调用时传递参数实现,因为函数的参数在栈中分配。
堆空间的分配主要是在需要使用动态内存的时候进行。
动态内存的使用可以解决一些静态内存无法解决的问题,例如存储用户输入的字符串内容、存储较大的数据表等。
在使用动态内存时,程序员需要注意动态内存分配后一定要及时释放,否则会出现内存泄漏的问题。
c语言的内存结构
c语言的内存结构C语言是一种高级编程语言,但实际上在计算机中运行时,C语言程序会被编译成可执行文件,然后在计算机内存中运行。
因此,了解C 语言的内存结构对于理解C程序的运行及性能优化至关重要。
C语言的内存结构主要可以分为以下几个部分:栈(Stack)、堆(Heap)、全局内存(Global Memory)和代码区(Code Segment)。
首先是栈(Stack),栈是一种自动分配和释放内存的数据结构。
它用于存储局部变量、函数参数和函数调用信息等。
栈的特点是后进先出(LIFO),也就是最后进入的数据最先被释放。
栈的大小在程序运行时是固定的,一般由编译器设置。
栈的操作速度较快,但内存空间有限。
其次是堆(Heap),堆是一种动态分配和释放内存的数据结构。
它用于存储动态分配的变量、数据结构和对象等。
堆的大小一般由操作系统管理,并且可以在运行时进行动态扩展。
堆的操作相对较慢,因为需要手动分配和释放内存,并且容易产生内存碎片。
全局内存(Global Memory)是用于存储全局变量和静态变量的区域。
全局变量在程序的生命周期内都存在,并且可以在多个函数之间共享。
静态变量作用于其所在的函数内,但是生命周期与全局变量相同。
全局内存由编译器进行分配和管理。
代码区(Code Segment)存储了程序的指令集合,它是只读的。
在程序运行时,代码区的指令会被一条一条地执行。
代码区的大小由编译器决定,并且在程序执行过程中不能修改。
此外,C语言还具有特殊的内存区域,如常量区和字符串常量区。
常量区用于存储常量数据,如字符串常量和全局常量等。
常量区的数据是只读的,且在程序的整个生命周期内存在。
字符串常量区是常量区的一个子区域,用于存储字符串常量。
在C语言中,内存分配和释放是程序员的责任。
通过使用malloc和free等函数,程序员可以在堆中动态地分配和释放内存,从而灵活地管理程序的内存使用。
不过,应当注意避免内存泄漏和野指针等问题,以免出现内存错误和性能问题。
c语言cpu分配内存的原则
c语言cpu分配内存的原则:
以下是一些关于C语言中内存分配的原则:
1.静态存储区:这部分内存是在程序编译时分配的,包括全局变量和静态变量。
这些
变量的生命周期是整个程序的执行期间。
2.栈内存:这部分内存是在程序执行期间动态分配的,主要用来存储函数调用的局部
变量和函数参数。
当函数执行结束时,这部分内存会自动释放。
3.堆内存:这是动态内存分配区域,通过malloc,calloc等函数分配。
当不再需要这部
分内存时,应使用free函数释放。
需要注意的是,如果不正确地使用这些函数(例如,试图释放同一块内存两次或者在释放内存后继续使用它),可能会导致程序崩溃或未定义的行为。
4.代码段:也称为文本段,这是用来存储程序的二进制代码的区域。
这部分内存通常
不可写,因为它是只读的,以防止程序意外地修改其指令。
5.运行时内存分配:C语言标准库提供了一些函数用于在运行时动态分配和释放内存,
如malloc()、calloc()、realloc()和free()。
这些函数允许程序员在运行时分配和释放内存,这在处理大量数据或需要根据程序运行情况动态调整数据结构大小时非常有用。
C语言中堆的名词解释
C语言中堆的名词解释堆(Heap)是C语言中的一种动态内存分配方式,它相对于栈(Stack)来说,拥有更大的内存空间并且能够存储具有更长生命周期的数据。
在本文中,我们将解释堆的概念、特性以及在C语言中的应用。
一、堆的概念和特性堆是C语言中一块动态分配的内存区域,用于存储程序运行期间需要长时间保留的数据。
与栈不同,堆的内存分配和释放并不自动管理,而是需要通过程序员手动控制。
堆的主要特性可以概括为以下几点:1. 大小可变:堆的大小取决于操作系统的内存限制,可以动态地增加或缩小。
2. 不连续性:堆内存中的数据块可以被随意分配和释放,它们的位置通常是不连续的。
3. 长生命周期:堆中分配的内存空间在程序运行期间一直存在,直到显式地释放。
4. 存储动态数据:堆用于存储运行时动态创建的数据,例如对象、数组、链表等。
二、堆的内存分配在C语言中,使用malloc函数来动态分配堆内存。
malloc的完整形式是memory allocation(内存分配),其原型如下:```cvoid* malloc(size_t size);malloc函数接受一个size_t类型的参数,表示需要分配的内存空间大小,返回一个void指针,指向分配的内存起始地址。
若分配失败,则返回一个空指针NULL。
以下是一个使用malloc分配堆内存的示例:```cint* ptr = (int*) malloc(sizeof(int));```在上述示例中,我们使用malloc函数分配了一个int类型的内存空间并将其地址赋值给了ptr指针。
这样,我们就可以通过访问ptr来操作这个堆内存空间。
需要注意的是,使用malloc函数分配的堆内存必须在使用完毕后通过调用free 函数来显式地释放,以避免内存泄漏。
free函数的原型如下:```cvoid free(void* ptr);```free函数接受一个void指针作为参数,指向需要释放的堆内存的起始地址。
C语言实现堆栈(自己的)
C语⾔实现堆栈(⾃⼰的)stack.h#ifndef __STACK_H__#define __STACK_H__#include <stdio.h>#include <stdlib.h>#include <stdbool.h>typedef int ElementType;struct SNode {ElementType *Data; /* 存储元素的数组 */int Top; /* 栈顶指针 */int MaxSize; /* 堆栈最⼤容量 */};typedef struct SNode *Stack;Stack CreateStack( int MaxSize ); //建⽴结构体堆栈bool IsFull( Stack S ); //判断堆栈是是否溢出bool Push( Stack S, ElementType X ); //压栈bool IsEmpty( Stack S ); //判断堆栈是是否为空ElementType Pop( Stack S ); //出栈#endifstack.c#include "stack.h"#include "sys.h"u8 Choose_Stack_Flag=0; //未检测到加减符号时候,0:⼀个结构体,检测到1:另⼀个结构体Stack CreateStack( int MaxSize ){Stack S = (Stack)malloc(sizeof(struct SNode));S->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));S->Top = -1;S->MaxSize = MaxSize;return S;}bool IsFull( Stack S ){return (S->Top == S->MaxSize-1);}bool Push( Stack S, ElementType X ){if ( IsFull(S) ) {printf("堆栈满");return false;}else {S->Data[++(S->Top)] = X;return true;}}bool IsEmpty( Stack S ){return (S->Top == -1);}ElementType Pop( Stack S ){if ( IsEmpty(S) ) {printf("堆栈空");return ERROR; /* ERROR是ElementType的特殊值,标志错误 ERROR 0 */}elsereturn ( S->Data[(S->Top)--] );}。
c语言堆栈和队列函数大全
C语言堆栈和队列函数大全一.顺序栈1.宏定义#include<stdio.h>#include<stdlib.h>#define MAXSIZE ****#define datatype ****2.结构体typedef struct{datatype data[MAXSIZE];int top;}Seqstack;3.基本函数Seqstack *Init_Seqstack()/*置空栈函数(初始化)1.先决条件:无;2.函数作用:首先建立栈空间,然后初始化栈顶指针,返回栈s的地址*/{Seqstack *s;s=(Seqstack *)malloc(sizeof(Seqstack));s->top=-1;return s;}int Empty_Seqstack(Seqstack *s) /*判栈空函数1.先决条件:初始化顺序栈;2.函数作用:判断栈是否为空,空返回1,不空返回0*/ {if(s->top==-1) return 1;else return 0;}int Push_Seqstack(Seqstack *s,datatype x) /*入栈函数1.先决条件:初始化顺序栈2.函数作用:将数据x入栈,栈满则不能,成功返回1,因栈满失败返回0*/ {if(s->top==MAXSIZE-1)return 0;s->top=s->top+1;s->data[s->top]=x;return 1;}int Pop_Seqstack(Seqstack *s,datatype *x) acidity, mL.; M--calibration of the molar concentration of sodium hydroxide standard solution, moI/L; V--amount of the volume of sodium hydroxide standard solution, Ml; M--the weight of the sample, g. Such as poor meets the requirements, take the arithmetic mean of the second determination as a result. Results one decimal. 6, allowing differential analyst simultaneously or in quick succession for the second determination, the absolute value of the difference of the results. This value should be no more than 1.0. 1, definitions and principles for determination of ash in starches, starch and ash: starch samples of ash the residue obtainedafter weight. Original sample residue weight of sample weight or weight expressed as a percentage of the dry weight of the sample. Samples ofash at 900 ? high temperature until ashing sample ... The Crucible: determination of Platinum or other conditions of the affected material, capacity of 50mL. Dryer: has effectively adequate drying agent and-perforated metal plate or porcelain. Ashing furnaces: device for controlling and regulating temperature, offers 900 incineration temperature of 25 c. Analytical balance. Electric hot plate or Bunsen. 3, crucible of analysis steps preparation: Crucible must first wash with boiling dilute hydrochloric acid, then wash with a lot of water and then rinse with distilled water. Wash the Crucible within ashing furnace, heated at 900 to 25 ? 30min, and in the desiccator to cool to room temperature and then weighing,/*出栈函数1.先决条件:初始化顺序栈2.函数作用:从栈中出一个数据,并将其存放到x中,成功返回1,因栈空失败返回0*/{if(s->top==-1)return 0;*x=s->data[s->top];s->top--;return 1;}int Top_Seqstack(Seqstack *s,datatype *x)/*取栈顶元素函数1.先决条件:初始化顺序栈2.函数作用:取栈顶元素,并把其存放到x中,成功返回1,因栈空失败返回0*/{if(s->top==-1)return 0;*x=s->data[s->top];return 1;}int Printf_Seqstack(Seqstack *s) /*遍历顺序栈函数1.先决条件:初始化顺序栈2.函数作用:遍历顺序栈,成功返回1*/ {int i,j=0;for(i=s->top;i>=0;i--){printf("%d ",s->data[i]);/*因datatype不同而不同*/j++;if(j%10==0)printf("\n");}printf("\n");return 1;}int Conversation_Seqstack(int N,int r) /*数制转换函数(顺序栈)1.先决条件:具有置空栈,入栈,出栈函数2.函数作用:将N转换为r进制的数*/{Seqstack *s;datatype x;printf("%d转为%d进制的数为:",N,r);/*以后可以删除去*/s=Init_Seqstack();do{Push_Seqstack(s,N%r);N=N/r;acidity, mL.; M--calibration of the molar concentration of sodium hydroxide standard solution, moI/L; V--amount of the volume of sodium hydroxide standard solution, Ml; M--the weight of the sample, g. Such as poor meets the requirements, take the arithmetic mean of the second determination as a result. Results one decimal. 6, allowing differential analyst simultaneously or in quick succession for the second determination, the absolute value of the difference of the results. This value should be no more than 1.0. 1, definitions and principles for determination of ash in starches, starch and ash: starch samples of ash the residue obtained after weight. Original sample residue weight of sample weight or weight expressed as a percentage of the dry weight of the sample. Samples of ash at 900 ? high temperature until ashing sample ... The Crucible: determination of Platinum or other conditions of the affected material, capacity of 50mL. Dryer: has effectivelyadequate drying agent and-perforated metal plate or porcelain. Ashing furnaces: device for controlling and regulating temperature, offers 900 incineration temperature of 25 c. Analytical balance. Electric hot plate or Bunsen. 3, crucible of analysis steps preparation: Crucible mustfirst wash with boiling dilute hydrochloric acid, then wash with a lot of water and then rinse with distilled water. Wash the Crucible within ashing furnace, heated at 900 to 25 ? 30min, and in the desiccator to cool to room temperature and then weighing,}while(N);while(Pop_Seqstack(s,&x)){if(x>=10)/*为了能转为十进制以上的*/printf("%c",x+55);elseprintf("%d",x);}free(s);/*释放顺序栈*/printf("\n");return 1;}4.主函数int main(){Seqstack *s;int choice;datatype x;do{printf("************************************************************ ****\n");printf("1.置空栈 2.判栈空 3.入栈 4.出栈 5.取栈顶元素 6.遍历 7.退出\n");printf("************************************************************ ****\n");printf("请输入选择(1~7):");scanf("%d",&choice);getchar();switch(choice){case 1:s=Init_Seqstack();if(s)printf("置空栈成功!\n");break;case 2:if(Empty_Seqstack(s))printf("此为空栈.\n");elseprintf("此不为空栈.\n");;break;case 3:printf("请输入一个整数:");scanf("%d",&x);if(Push_Seqstack(s,x))printf("入栈成功.\n");elseprintf("栈已满,无法入栈.\n");;break;case 4:if(Pop_Seqstack(s,&x)) acidity, mL.; M--calibration of the molar concentration of sodium hydroxide standard solution, moI/L; V--amount of the volume of sodium hydroxide standard solution, Ml; M--the weight of the sample, g. Such as poor meets the requirements, take the arithmetic mean of the second determination as a result. Results one decimal. 6, allowing differential analyst simultaneously or in quick succession for the second determination, the absolute value of the difference of the results. This value should be no more than 1.0. 1, definitions and principles for determination of ash in starches, starch and ash: starch samples of ash the residue obtained after weight. Original sample residue weight of sample weight or weight expressed as a percentage of the dry weight of the sample. Samples of ash at 900 ? high temperature until ashing sample ... The Crucible: determination of Platinum or other conditions of the affected material, capacity of 50mL. Dryer: has effectively adequate drying agent and-perforated metal plate or porcelain. Ashing furnaces: device for controlling and regulating temperature, offers 900 incineration temperature of 25 c. Analytical balance. Electric hot plate or Bunsen. 3, crucible of analysis steps preparation: Crucible must first wash with boiling dilute hydrochloric acid, then wash with a lot of water and then rinse with distilled water.Wash the Crucible within ashing furnace, heated at 900 to 25 ? 30min, and in the desiccator to cool to room temperature and then weighing, printf("出栈成功,出栈元素为:%d\n",x);elseprintf("出栈失败,因栈为空.\n");break;case 5:if(Top_Seqstack(s,&x))printf("取栈顶元素成功,栈顶元素为:%d\n",x);elseprintf("取栈顶元素失败,因栈为空.\n");break;case 6:Printf_Seqstack(s);break;case 7:printf("谢谢使用!\n");break;default :printf("输入错误,请重新输入!\n");break;}}while(choice!=7);return 0;}二.链栈1.宏定义#include<stdio.h>#include<stdlib.h>#define datatype ****2.结构体typedef struct snode{datatype data;struct snode *next;}Stacknode,*Linkstack;3.基本函数Linkstack Init_Linkstack()/*初始化栈函数1.先决条件:无2.函数作用:初始化链栈,返回top地址*/ { Linkstack top;top=(Linkstack)malloc(sizeof(Stacknode));top->next=NULL;return top;}int Empty_Linkstack(Linkstack top) /*判栈空函数1.先决条件:初始化链栈2.函数作用:判断栈是否为空,空返回1,不空返回0*/{if(top->next==NULL)acidity, mL.; M--calibration of the molar concentration of sodium hydroxide standard solution, moI/L; V--amount of the volume of sodium hydroxide standard solution, Ml; M--the weight of the sample, g. Such as poor meets the requirements, take the arithmetic mean of the second determination as a result. Results one decimal. 6, allowing differential analyst simultaneously or in quick succession for the second determination, the absolute value of the difference of the results. This value should be no more than 1.0. 1, definitions and principles fordetermination of ash in starches, starch and ash: starch samples of ash the residue obtained after weight. Original sample residue weight of sample weight or weight expressed as a percentage of the dry weight of the sample. Samples of ash at 900 ? high temperature until ashing sample ... The Crucible: determination of Platinum or other conditions of the affected material, capacity of 50mL. Dryer: has effectively adequate drying agent and-perforated metal plate or porcelain. Ashing furnaces: device for controlling and regulating temperature, offers 900 incineration temperature of 25 c. Analytical balance. Electric hot plate or Bunsen. 3, crucible of analysis steps preparation: Crucible mustfirst wash with boiling dilute hydrochloric acid, then wash with a lot of water and then rinse with distilled water. Wash the Crucible within ashing furnace, heated at 900 to 25 ? 30min, and in the desiccator to cool to room temperature and then weighing,return 1;else return 0;}int Push_Linkstack(Linkstack top,datatype x) /*入栈函数1.先决条件:初始化链栈2.函数作用:将数据x入栈,成功返回1,失败返回0*/ { Stacknode *p;p=(Stacknode *)malloc(sizeof(Stacknode));p->data=x;p->next=top->next;top->next=p;return 1;}int Pop_Linkstack(Linkstack top,datatype *x) /*出栈函数1.先决条件:初始化链栈2.函数作用:若栈空退出,若没空则将数据出栈,并将其存放到x中,成功返回1,因栈空失败返回0*/{if(top->next==NULL)return 0;Stacknode *p=top->next;*x=p->data;top->next=p->next;free(p);return 1;}int Top_Linkstack(Linkstack top,datatype *x) /*取栈顶元素函数1.先决条件:初始化链栈2.函数作用:取栈顶元素并放到x中,成功返回1,因栈空失败返回0*/{if(top->next==NULL)return 0;*x=top->next->data;return 1;}int Printf_Linkstack(Linkstack top) /*遍历链栈函数1.先决条件:初始化链栈2.函数作用:遍历链栈,成功返回1*/ {Stacknode *p=top->next;int j=0;while(p){printf("%d ",p->data);/*因datatype不同而不同*/j++;if(j%10==0)acidity, mL.; M--calibration of the molar concentration of sodium hydroxide standard solution, moI/L; V--amount of the volume of sodium hydroxide standard solution, Ml; M--the weight of the sample, g. Such as poor meets the requirements, take the arithmetic mean of the second determination as a result. Results one decimal. 6, allowing differential analyst simultaneously or in quick succession for the second determination, the absolute value of the difference of the results. This value should be no more than 1.0. 1, definitions and principles for determination of ash in starches, starch and ash: starch samples of ash the residue obtained after weight. Original sample residue weight of sample weight or weight expressed as a percentage of the dry weight of the sample. Samples of ash at 900 ? high temperature until ashing sample ... The Crucible: determination of Platinum or other conditions of the affected material, capacity of 50mL. Dryer: has effectively adequate drying agent and-perforated metal plate or porcelain. Ashingfurnaces: device for controlling and regulating temperature, offers 900 incineration temperature of 25 c. Analytical balance. Electric hot plate or Bunsen. 3, crucible of analysis steps preparation: Crucible mustfirst wash with boiling dilute hydrochloric acid, then wash with a lot of water and then rinse with distilled water. Wash the Crucible within ashing furnace, heated at 900 to 25 ? 30min, and in the desiccator to cool to room temperature and then weighing,printf("\n");p=p->next;}printf("\n");return 1;}int Conversation_Linkstack(int N,int r)/*数制转换函数(链栈)1.先决条件:具有置空栈,入栈,出栈函数2.函数作用:将N转换为r进制的数*/{Linkstack top;datatype x;printf("%d转为%d进制的数为:",N,r);/*以后可以删除去*/top=Init_Linkstack();do{Push_Linkstack(top,N%r);N=N/r;}while(N);while(Pop_Linkstack(top,&x)){if(x>=10)/*为了能转为十进制以上的*/printf("%c",x+55);elseprintf("%d",x);}printf("\n");free(top);/*释放栈顶空间*/return 1;}4.主函数int main(){Linkstack top;int choice;datatype x;do{printf("************************************************************ ****\n");printf("1.置空栈 2.判栈空 3.入栈 4.出栈 5.取栈顶元素 6.遍历 7.退出\n");printf("************************************************************ ****\n");printf("请输入选择(1~7):");acidity, mL.; M--calibration of the molar concentration of sodium hydroxide standard solution, moI/L; V--amount of the volume of sodium hydroxide standard solution, Ml; M--the weight of the sample, g. Such as poor meets the requirements, take the arithmetic mean of the second determination as a result. Results one decimal. 6, allowing differential analyst simultaneously or in quick succession for the second determination, the absolute value of the difference of the results. This value should be no more than 1.0. 1, definitions and principles for determination of ash in starches, starch and ash: starch samples of ash the residue obtained after weight. Original sample residue weight of sample weight or weight expressed as a percentage of the dry weight of the sample. Samples of ash at 900 ? high temperature until ashing sample ... The Crucible: determination of Platinum or other conditions of the affected material, capacity of 50mL. Dryer: has effectively adequate drying agent and-perforated metal plate or porcelain. Ashing furnaces: device for controlling and regulating temperature, offers 900 incineration temperature of 25 c. Analytical balance. Electric hot plate or Bunsen. 3, crucible of analysis steps preparation: Crucible mustfirst wash with boiling dilute hydrochloric acid, then wash with a lotof water and then rinse with distilled water. Wash the Crucible within ashing furnace, heated at 900 to 25 ? 30min, and in the desiccator to cool to room temperature and then weighing,scanf("%d",&choice);getchar();switch(choice){case 1:top=Init_Linkstack();if(top)printf("置空栈成功!\n");break;case 2:if(Empty_Linkstack(top))printf("此为空栈.\n");elseprintf("此不为空栈.\n");;break;case 3:printf("请输入一个整数:");scanf("%d",&x);if(Push_Linkstack(top,x))printf("入栈成功.\n");elseprintf("栈已满,无法入栈.\n");;break;case 4:if(Pop_Linkstack(top,&x))printf("出栈成功,出栈元素为:%d\n",x);elseprintf("出栈失败,因栈为空.\n");break;case 5:if(Top_Linkstack(top,&x))printf("取栈顶元素成功,栈顶元素为:%d\n",x);elseprintf("取栈顶元素失败,因栈为空.\n");break;case 6:Printf_Linkstack(top);break;case 7:printf("谢谢使用!\n");break;default :printf("输入错误,请重新输入!\n");break;}}while(choice!=7);return 0;}二.队列1.宏定义2.结构体3.基本函数4.主函数acidity, mL.; M--calibration of the molar concentration of sodium hydroxide standard solution, moI/L; V--amount of the volume of sodium hydroxide standard solution, Ml; M--the weight of the sample, g. Such as poor meets the requirements, take the arithmetic mean of the second determination as a result. Results one decimal. 6, allowing differential analyst simultaneously or in quick succession for the second determination, the absolute value of the difference of the results. Thisvalue should be no more than 1.0. 1, definitions and principles for determination of ash in starches, starch and ash: starch samples of ash the residue obtained after weight. Original sample residue weight of sample weight or weight expressed as a percentage of the dry weight of the sample. Samples of ash at 900 ? high temperature until ashing sample ... The Crucible: determination of Platinum or other conditions of the affected material, capacity of 50mL. Dryer: has effectively adequate drying agent and-perforated metal plate or porcelain. Ashing furnaces: device for controlling and regulating temperature, offers 900 incineration temperature of 25 c. Analytical balance. Electric hot plate or Bunsen. 3, crucible of analysis steps preparation: Crucible mustfirst wash with boiling dilute hydrochloric acid, then wash with a lot of water and then rinse with distilled water. Wash the Crucible within ashing furnace, heated at 900 to 25 ? 30min, and in the desiccator to cool to room temperature and then weighing,。
C语言堆和栈的区别
堆和栈的区别一、预备知识—程序的内存分配一个由c/C++编译的程序占用的内存分为以下几个部分1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。
其操作方式类似于数据结构中的栈。
2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。
注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
- 程序结束后有系统释放4、文字常量区—常量字符串就是放在这里的。
程序结束后由系统释放5、程序代码区—存放函数体的二进制代码。
二、例子程序这是一个前辈写的,非常详细//main.cppint 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"优化成一个地方。
}二、堆和栈的理论知识2.1申请方式stack:由系统自动分配。
例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间heap:需要程序员自己申请,并指明大小,在c中malloc函数如p1 = (char *)malloc(10);在C++中用new运算符如p2 = (char *)malloc(10);但是注意p1、p2本身是在栈中的。
什么是堆什么是栈
五大内存分区在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。
里面的变量通常是局部变量、函数参数等。
堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。
如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多)明确区分堆与栈在bbs上,堆与栈的区分问题,似乎是一个永恒的话题,由此可见,初学者对此往往是混淆不清的,所以我决定拿他第一个开刀。
首先,我们举一个例子:void f() { int* p=new int[5]; }这条短短的一句话就包含了堆与栈,看到new,我们首先就应该想到,我们分配了一块堆内存,那么指针p呢?他分配的是一块栈内存,所以这句话的意思就是:在栈内存中存放了一个指向一块堆内存的指针p。
在程序会先确定在堆中分配内存的大小,然后调用operator new分配内存,然后返回这块内存的首地址,放入栈中,他在VC6下的汇编代码如下:00401028 push 14h0040102A call operator new (00401060)0040102F add esp,400401032 mov dword ptr [ebp-8],eax00401035 mov eax,dword ptr [ebp-8]00401038 mov dword ptr [ebp-4],eax这里,我们为了简单并没有释放内存,那么该怎么去释放呢?是delete p么?澳,错了,应该是delete []p,这是为了告诉编译器:我删除的是一个数组,VC6就会根据相应的Cookie信息去进行释放内存的工作。
C语言的内存优化与内存访问模式
内存优化与内存访问模式在编程中,内存是一个非常重要的资源。
尤其是对于一些需要高效运行的程序,优化内存的使用成为了一个关键的因素。
而C语言作为一种底层语言,对内存的访问和使用有着很大的灵活性和控制能力。
本文将探讨C语言中的内存优化技巧和内存访问模式,帮助开发者们更好地掌握内存的使用。
1. 内存分配与释放函数在C语言中,使用malloc函数可以动态分配内存,free函数用于释放已分配的内存。
这样可以根据需要动态地管理内存的分配和释放。
然而,在实际使用中需要注意以下几点: - 动态分配的内存需要在使用完毕后及时释放,避免内存泄漏。
- 动态分配的内存大小应合理,避免过度分配导致内存浪费,或者分配不足导致缓冲区溢出等问题。
- 注意检查分配内存的返回值,判断是否分配成功。
2. 栈与堆内存的区别在C语言中,有两种方式可以分配内存:栈内存和堆内存。
栈内存的分配是由编译器自动管理的,而堆内存则需要手动分配和释放。
两者之间存在一些区别:- 栈内存的分配速度较快,由编译器自动管理,而堆内存的分配需要显式地调用malloc函数。
- 栈内存的生命周期是由函数的调用来决定的,函数执行完毕后自动释放,而堆内存需要手动调用free函数来释放。
- 栈内存的大小有限,并且分配的内存是连续的,而堆内存可以分配较大的内存,且分配的内存不一定是连续的。
3. 避免频繁的内存分配与释放频繁地进行内存分配和释放操作会增加程序的开销和内存碎片,降低程序的效率。
因此,在实际编程中,应尽量避免频繁的内存分配和释放操作。
- 可以通过一次性分配多个内存块,而不是每次只分配一个,来减少内存分配的次数。
- 对于需要频繁使用的对象,可以使用对象池技术,事先分配一定数量的内存块,并进行复用。
这样就可以避免频繁地进行内存分配和释放操作。
4. 缓存友好的内存访问在现代计算机中,缓存的作用非常重要,良好的内存访问模式可以提高程序的性能。
而在C语言中,由于存在指针的概念,对内存的访问模式有着更大的控制能力。
c语言中内存分配的几种方式
c语言中内存分配的几种方式
在C语言中,内存的管理是非常重要的。
C语言提供了多种内存分配的方式,可以根据不同情况选择不同的方式进行内存分配。
以下是C语言中内存分配的几种方式。
1. 静态内存分配
静态内存分配是在程序编译时就确定了内存的大小和分配位置,这种方式不需要在程序运行时进行内存分配。
在C语言中,静态内存分配可以通过定义全局变量或静态变量来实现。
2. 栈内存分配
栈内存分配是指在函数内部定义的变量所分配的内存。
当函数被调用时,栈被分配一段内存用来存储函数的局部变量,当函数返回时,这段内存会被释放。
栈内存分配的好处是速度快,但是分配的内存大小受限于栈的大小。
3. 堆内存分配
堆内存分配是指程序在运行时通过malloc()函数或calloc()函数动态分配内存。
堆内存的好处是大小灵活,但是需要手动释放,否则容易出现内存泄漏的问题。
4. 内存映射文件
内存映射文件是指将一个文件映射到内存中,使得程序可以直接访问文件中的数据。
在C语言中,可以使用mmap()函数将文件映射到内存中。
总结
在C语言中,内存的管理是非常重要的。
根据不同的情况可以选择不同的内存分配方式,如静态内存分配、栈内存分配、堆内存分配和内存映射文件等。
合理的内存管理可以提高程序的性能和稳定性。
C语言内存管理堆栈和静态存储区
C语言内存管理堆栈和静态存储区C语言内存管理:堆、栈和静态存储区C语言作为一种高效而强大的编程语言,其内存管理是程序员必须掌握的重要内容之一。
本文将重点介绍C语言中的内存管理中的堆、栈以及静态存储区。
一、堆堆是C语言中用于动态内存分配的一块内存区域。
在程序运行时,可以通过函数malloc()和calloc()来申请堆空间,通过函数free()来释放堆空间。
堆的特点:1. 大小可变:堆中的内存空间大小可以在程序运行时进行动态调整。
2. 生命周期自由控制:通过malloc()或calloc()分配的堆空间,在不再使用后,需要程序员手动调用free()函数进行释放。
堆的使用场景:1. 动态数组:当程序无法预先知道数组大小时,可以使用堆来动态申请空间。
2. 链表:链表结构通常需要通过堆来进行动态内存分配。
二、栈栈是C语言中用于函数调用和局部变量存储的一块内存区域。
在函数调用过程中,栈会记录函数的调用顺序、调用参数以及局部变量等。
栈的特点:1. 后进先出:栈是一种后进先出(LIFO)的数据结构,函数调用时会依次将函数入栈,并在函数返回时依次出栈。
2. 自动管理:栈内存的分配和释放是由编译器自动完成的,程序员无需手动管理。
栈的使用场景:1. 函数调用:栈用于管理函数的调用顺序以及函数内部的局部变量。
2. 递归:递归函数的调用过程涉及到栈的递归压栈和递归出栈。
三、静态存储区静态存储区是C语言中使用static关键字声明的变量所存储的内存区域。
在程序运行期间,静态变量在内存中的位置始终不变,且仅在程序结束时才会释放。
静态存储区的特点:1. 生命周期长:静态变量在程序运行期间都存在,不依赖于函数的调用和返回。
2. 全局可访问:静态变量可以在整个程序中被访问,不受函数作用域的限制。
静态存储区的使用场景:1. 全局变量:使用static关键字声明的全局变量存储在静态存储区中,可以在整个程序中被访问。
2. 共享数据:多个函数之间需要共享的数据可以使用静态变量来实现。
C++中堆和栈的完全解析
C++中堆和栈的完全解析内存分配方面:堆:操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样代码中的delete语句才能正确的释放本内存空间。
我们常说的内存泄露,最常见的就是堆泄露(还有资源泄露),它是指程序在运行中出现泄露,如果程序被关闭掉的话,操作系统会帮助释放泄露的内存。
栈:在函数调用时第一个进栈的主函数中的下一条指令(函数调用语句的下一条可执行语句)的地址然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈,然后是函数中的局部变量。
一、预备知识—程序的内存分配一个由c/C++编译的程序占用的内存分为以下几个部分1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。
其操作方式类似于数据结构中的栈。
2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。
注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
- 程序结束后有系统释放4、文字常量区—常量字符串就是放在这里的。
程序结束后由系统释放5、程序代码区—存放函数体的二进制代码。
有些说法,把3,4合在一起,也有的把3分成自由存储区(malloc/free)和全局/静态存储区。
这与编译器和操作系统有关。
二、例子程序这是一个前辈写的,非常详细//main.cppint a = 0; 全局初始化区char *p1; 全局未初始化区main(){int b; 栈char s[] = "abc"; 栈//更正:abc 分配在静态存储区,不是栈上char *p2; 栈char *p3 = "123456"; 123456\0在常量区,p3在栈上。
c语言中的堆栈
c语言中的堆栈摘要:1.堆栈的概念与作用2.C语言中的堆栈实现3.堆栈的使用方法与注意事项4.堆栈溢出的原因及预防5.堆栈在编程中的应用实例正文:堆栈是计算机科学中一种重要的数据结构,主要用于实现函数调用、局部变量存储以及算法递归等功能。
在C语言中,堆栈有着广泛的应用,下面我们将详细介绍堆栈的相关知识。
1.堆栈的概念与作用堆栈是一种线性数据结构,遵循后进先出(LIFO)的原则。
堆栈分为栈顶和栈底,数据元素在栈中按照顺序排列,只有栈顶元素可以被访问和修改,其他元素则无法直接访问。
堆栈的主要作用有以下几点:- 函数调用:C语言中,函数调用是通过堆栈来实现的。
每当一个函数被调用,它的局部变量、返回地址等信息会被压入堆栈。
函数执行完毕后,堆栈会将这些信息弹出,恢复调用者的状态。
- 局部变量存储:在C语言中,局部变量的存储也是通过堆栈来实现的。
当进入一个函数时,局部变量会被压入堆栈;函数执行完毕后,局部变量会被自动弹出。
- 算法递归:递归算法通常使用堆栈来保存递归调用时的中间结果,从而避免重复计算。
2.C语言中的堆栈实现C语言中的堆栈是由操作系统提供的,通常使用一组固定大小的内存区域来实现。
堆栈的增长方向是向下的,堆栈指针指向栈顶元素。
在C语言中,堆栈的操作主要包括入栈(push)和出栈(pop)两种。
3.堆栈的使用方法与注意事项使用堆栈时,需要注意以下几点:- 避免堆栈溢出:堆栈空间是有限的,如果栈中的元素数量过多,会导致堆栈溢出。
因此,在使用堆栈时,需要合理控制栈的大小,避免长时间递归调用或大量使用局部变量。
- 遵循栈的生长方向:在C语言中,堆栈的生长方向是向下的,因此入栈操作会使栈顶指针减小,出栈操作会使栈顶指针增大。
- 注意栈的操作顺序:在函数调用中,先入栈的是函数的返回地址,然后是局部变量;函数执行完毕后,首先弹出的是局部变量,然后是返回地址。
4.堆栈溢出的原因及预防堆栈溢出是由于栈中的元素数量过多,导致栈空间不足而引发的。
c语言实现栈详细代码
c语言实现栈详细代码栈(Stack),又称堆栈,是一种后进先出(LIFO,Last In First Out)的数据结构,它只允许在一段端点进行插入和删除操作,这个端点被称为栈顶。
C语言实现栈的基本思路是建立一个结构体,结构体中包含一个数组和栈顶指针top。
数组用来存放栈中元素,top指针指向栈顶元素的下标。
实现栈的操作包括压栈(push)、出栈(pop)和获取栈顶元素(get_top)。
下面是详细代码:```#include <stdio.h>#include <stdlib.h>#define MAX_SIZE 100 //栈的最大长度typedef struct stack {int data[MAX_SIZE]; //栈中元素int top; //栈顶指针} Stack;//初始化栈void init(Stack *s) {s->top = -1; //栈顶指针初始化为-1,表示栈为空}//判断栈是否为空int is_empty(Stack *s) {return s->top == -1;}//判断栈是否已满int is_full(Stack *s) {return s->top == MAX_SIZE-1;}//压栈void push(Stack *s, int value) {if (is_full(s)) {printf("Stack is full, cannot push!\n");return;}s->data[++(s->top)] = value; //栈顶指针先加1,再将元素入栈}//出栈void pop(Stack *s) {if (is_empty(s)) {printf("Stack is empty, cannot pop!\n");}s->top--; //栈顶指针减1,表示栈顶元素已删除}//获取栈顶元素int get_top(Stack *s) {if (is_empty(s)) {printf("Stack is empty, cannot get top element!\n"); return -1;}return s->data[s->top]; //返回栈顶元素}int main() {Stack s;init(&s); //初始化栈for (i = 0; i < 5; i++) {push(&s, i); //压入5个元素}printf("Top element: %d\n", get_top(&s)); //获取栈顶元素while (!is_empty(&s)) {printf("%d ", get_top(&s)); //依次输出栈中元素pop(&s); //弹出栈顶元素}return 0;}```代码中定义了一个结构体,包含一个整型数组data和一个整型变量top,数组用来存放栈中元素,top表示栈顶指针。
一文搞懂栈(stack)、堆(heap)、单片机裸机内存管理malloc
一文搞懂栈(stack)、堆(heap)、单片机裸机内存管理malloc大家好,我是无际。
有一周没水文了,俗话说夜路走多了难免遇到鬼。
最近就被一个热心网友喷了。
说我的文章没啥营养,所以今天来一篇烧脑的。
哈哈,开个玩笑,不要脸就没人能把我绑架。
主要是最近研发第二代物联网网关项目,必须要用到一个功能:内存管理。
温馨提醒,全文4700多字,其中技术点是你进阶到高手必须要学习的,最好收藏,反复专注地看,否则可能会感觉在看天书。
说到内存管理大家会可能想到malloc和free函数。
在讲这两个函数之前,我们先来讲讲栈(stack)和堆(heap)的概念。
1.栈(stack)我们单片机一般有个启动文件,拿STM32F103来举例。
这个Stack_Size就是栈大小,0x00000400就是代表有1K (0x400/1024)的大小。
那这个栈到底用来干嘛的呢?比如说我们函数的形参、以及函数里定义的局部变量就是存储在栈里,所以我们在函数的局部变量、数组这些不能超过1K(含嵌套的函数),否则程序就会崩溃进入hardfaul。
除了这些局部变量以外,还有一些实时操作系统的现场保护、返回地址都是存储在栈里面。
还有一点题外话,就是栈的增长方向是从高地址到低地址的,这个用得不多,暂时不需要去深究。
2. 堆(heap)malloc()函数动态分配的内存就属于堆的空间。
同样,在单片机启动文件里也有对堆大小的定义。
0x00000200就是代表有512个字节。
这意味着如果你用malloc()函数,那么最大分配的内存不能大于512字节,否则程序会崩溃。
网上很多文章说,全局变量和静态变量是放在堆区。
但是我做了实验,把堆的空间大小设置成0,程序正常运行并无影响。
这说明我们平时定义的全局变量、静态变量是不存放在堆的,而是堆栈以外的另外一篇静态空间区域,个人理解,如果有误请指正。
Ok,那么我们简单了解了堆和栈的概念,也知道malloc()函数分配的是堆的空间。
堆和栈的理解
堆和栈的理解
堆:堆是一种常用的存储结构,属于一种特殊的树形结构。
它一般用
于申请内存,可以根据具体的需要,动态地为程序分配和释放内存,使程
序可以根据其运行需求,随时调整内存的使用量。
堆的优点是可以满足复
杂的内存需求,方便程序员申请和释放内存,但是堆的缺点是由于动态分
配内存,每次申请内存和释放内存都会耗费大量的时间开销和空间开销。
栈:栈是一种常用的存储结构,它特别适合处理数据的“后进先出”机制。
它是一种特殊的线性表,具有先进后出的原则,栈顶指向栈中最后一个存
储的元素。
栈主要用来储存函数调用时的信息,因此也称为调用栈。
栈的
优点是操作简单,易于书写,而且存取的时间复杂度低,但是栈的缺点是
只允许在一端进行插入和删除操作,因此数据的存取是有限的。
dui堆和zhan栈的区别
堆是随机存放的但是栈却是只能够先进后出int a,b;int n=10;int func(){int m=10;a=m*3;b=n*3;return 0;}int main(){fumc();return 0;}在C++中,内存分成4个区,他们分别是堆,栈,静态存储区和常量存储区1)栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区.里面的变量通常是局部变量,函数参数等.2)堆,又叫自由存储区,它是在程序执行的过程中动态分配的,它最大的特性就是动.态性.由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete.如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收.如果分配了堆对象,却忘记了释放,就会产生内存泄漏.而如果已释放了对象,却没有将相应的指针置为NULL,该指针就是"悬挂指针".4)静态存储区.所有的静态对象,全局对象都于静态存储区分配.5)常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多)常量字符串都存放在静态存储区,返回的是常量字符串的首地址.n是全局变量,储存在静态区.进入main函数之前就被创建.生命周期为整个源程序.m是局部变量,在栈中分配.在函数func被调用时才被创建.生命周期为函数func内.n只创建一次.m每次调用func都会创建,函数结束就销毁.在pc上面堆是从上往下的栈是从下往上的数据段存放全局变量静态变量和常量和malloc申请的的动态空间(堆)就是堆代码段存着程序代码堆栈段存着子程序的返回地址子程序入口参数和程序的局部变量就是栈静态变量和全局变量,malloc申请的动态内存空间,一般都是存放在堆中栈中存放的是子函数入口的临时变量或局部变量摘自Thinking in java第一版===========================2.2.1 保存到什么地方程序运行时,我们最好对数据保存到什么地方做到心中有数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
在计算机领域,堆栈是一个不容忽视的概念,我们编写的C语言程序基本上都要用到。
但对于很多的初学着来说,堆栈是一个很模糊的概念。
堆栈:一种数据结构、一个在程序运
行时用于存放的地方,这可能是很多初学者的认识,因为我曾经就是这么想的和汇编语言中
的堆栈一词混为一谈。
我身边的一些编程的朋友以及在网上看帖遇到的朋友中有好多也说不
清堆栈,所以我想有必要给大家分享一下我对堆栈的看法,有说的不对的地方请朋友们不吝
赐教,这对于大家学习会有很大帮助。
首先在数据结构上要知道堆栈,尽管我们这么称呼它,但实际上堆栈是两种数据结构:堆和栈。
堆和栈都是一种数据项按序排列的数据结构。
我们先从大家比较熟悉的栈说起吧,它是一种具有后进先出性质的数据结构,也就是说
后存放的先取,先存放的后取。
这就如同我们要取出放在箱子里面底下的东西(放入的比较
早的物体),我们首先要移开压在它上面的物体(放入的比较晚的物体)。
而堆就不同了,堆
是一种经过排序的树形数据结构,每个结点都有一个值。
通常我们所说的堆的数据结构,是
指二叉堆。
堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。
由于
堆的这个特性,常用来实现优先队列,堆的存取是随意,这就如同我们在图书馆的书架上取
书,虽然书的摆放是有顺序的,但是我们想取任意一本时不必像栈一样,先取出前面所有的
书,书架这种机制不同于箱子,我们可以直接取出我们想要的书。
然而我要说的重点并不在这,我要说的堆和栈并不是数据结构的堆和栈,之所以要说数
据结构的堆和栈是为了和后面我要说的堆区和栈区区别开来,请大家一定要注意。
下面就说说C语言程序内存分配中的堆和栈,这里有必要把内存分配也提一下,大家不
要嫌我啰嗦,一般情况下程序存放在Rom或Flash中,运行时需要拷到内存中执行,内存会分
别存储不同的信息,如下图所示:
内存中的栈区处于相对较高的地址以地址的增长方向为上的话,栈地址是向下增长的,
栈中分配局部变量空间,堆区是向上增长的用于分配程序员申请的内存空间。
另外还有静态区是分配静态变量,全局变量空间的;只读区是分配常量和程序代码空间的;以及其他一些分区。
来看一个网上很流行的经典例子:
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); 堆
}
不知道你是否有点明白了,堆和栈的第一个区别就是申请方式不同:栈(英文名称
是stack)是系统自动分配空间的,例如我们定义一个char a;系统会自动在栈上为其开辟空间。
而堆(英文名称是heap)则是程序员根据需要自己申请的空间,例如malloc(10);开辟十个字节的空间。
由于栈上的空间是自动分配自动回收的,所以栈上的数据的生存周期只是在函数的运行过程中,运行后就释放掉,不可以再访问。
而堆上的数据只要程序员不释放空间,就一直可以访问到,不过
缺点是一旦忘记释放会造成内存泄露。
还有其他的一些区
别我认为网上的朋友总结的不错这里转述一下:
1.申请后系统的响应
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。
另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。
也就是说堆会在申请后还要做一些后续的工作这就会引出申请效率的问题。
2.申请效率的比较
栈:由系统自动分配,速度较快。
但程序员是无法控制的。
堆:是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。
3.申请大小的限制
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。
这句话的意思
是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的
说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示
overflow。
因此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。
这是由于系统是用链表来存储的
空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。
堆的大小受限
于计算机系统中有效的虚拟内存。
由此可见,堆获得的空间比较灵活,也比较大。
4.堆和栈中的存储内容
栈:在函数调用时,第一个进栈的是主函数中函数调用后的下一条指令(函数调用语句的下
一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左
入栈的,然后是函数中的局部变量。
注意静态变量是不入栈的。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的
地址,也就是主函数中的下一条指令,程序由该点继续运行。
堆:一般是在堆的头部用一个字节存放堆的大小。
堆中的具体内容有程序员安排。
5.存取效率的比较
char s1[] = "aaaaaaaaaaaaaaa";
char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在运行时刻赋值的;
而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
比如:
#include
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 movcl,byteptr [ebp-0Fh]
0040106A 88 4D FC mov byte ptr [ebp-4],cl
11: a = p[1];
0040106D 8B 55 EC movedx,dwordptr [ebp-14h]
00401070 8A 42 01 moval,byteptr [edx+1]
00401073 88 45 FC mov byte ptr [ebp-4],al
堆和栈的区别可以引用一位前辈的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了
就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自
由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。
比喻很形象,说的很通俗易懂,不知道你是否有点收获。
本文来自CSDN博客,转载请标明出处:/lfj200701/archive/2010/06/11/5665165.aspx。