内存的静态分配和动态分配

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

内存的静态分配和动态分配

内存的静态分配和动态分配的区别主要是两个:

一是时间不同。静态分配发生在程序编译和连接的时候。动态分配则发生在程序调入和执行的时候。

二是空间不同。堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由函数malloc进行分配。不过栈的动态分配和堆不同,他的动态分配是由编译器进行释放,无需我们手工实现。

对于一个进程的内存空间而言,可以在逻辑上分成3个部份:代码区,静态数据区和动态数据区。

动态数据区一般就是“堆栈”。“栈(stack)”和“堆(heap)”是两种不同的动态数据区,栈是一种线性结构,堆是一种链式结构。进程的每个线程都有私有的“栈”,所以每个线程虽然代码一样,但本地变量的数据都是互不干扰。一个堆栈可以通过“基地址”和“栈顶”地址来描述。全局变量和静态变量分配在静态数据区,本地变量分配在动态数据区,即堆栈中。程序通过堆栈的基地址和偏移量来访问本地变量。

一般,用static修饰的变量,全局变量位于静态数据区。函数调用过程中的参数,返回地址,EBP和局部变量都采用栈的方式存放。

所谓动态内存分配就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不象数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序要求的大小。

例如我们定义一个float型数组:

float score[100];

但是,在使用数组的时候,总有一个问题困扰着我们:数组应该有多大?在很多的情况下,你并不能确定要使用多大的数组,比如上例,你可能并不知道我们要定义的这个数组到底有多大,那么你就要把数组定义得足够大。这样,你的程序在运行时就申请了固定大小的你认为足够大的内存空间。即使你知道你想利用的空间大小,但是如果因为某种特殊原因空间利用的大小有增加或者减少,你又必须重新去修改程序,扩大数组的存储范围。这种分配固定大小的内存分配方法称之为静态内存分配。但是这种内存分配的方法存在比较严重的缺陷,特别是处理某些问题时:在大多数情况下会浪费大量的内存空间,在少数情况下,当你定义的数组不够大时,可能引起下标越界错误,甚至导致严重后果。

我们用动态内存分配就可以解决上面的问题. 所谓动态内存分配就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不象数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的

需要即时分配,且分配的大小就是程序要求的大小。从以上动、静态内存分配比较可以知道动态内存分配相对于景泰内存分配的特点:

1、不需要预先分配存储空间;

2、分配的空间可以根据程序的需要扩大或缩小。

要实现根据程序的需要动态分配存储空间,就必须用到malloc函数.

malloc函数的原型为:void *malloc (unsigned int size)

其作用是在内存的动态存储区中分配一个长度为size的连续空间。其参数是一个无符号整形数,返回值是一个指向所分配的连续存储域的起始地址的指针。还有一点必须注意的是,当函数未能成功分配存储空间(如内存不足)就会返回一个NULL指针。所以在调用该函数时应该检测返回值是否为NULL并执行相应的操作。

静态内存是在程序一开始运行就会分配内存,直到程序结束了,内存才被释放。动态内存是在程序调用在程序中定义的函数时才被分配,函数调用结束了,动态内存就释放。

static int a; /* 这是定义了一个静态的变量 */

int a; /* 这是定义了一个动态的变量; */

/* 静态内存可以用于求阶层。*/

jiechen( int i )

{

static int a = 1;

for (; a <= i, a++ )

return(a * i);

}

#include "stdio.h"

main()

{

int a, i;

printf( "enter number:" )

scanf( "%d", &a );

for ( i = 1; i <= a; i++ )

printf( "i!=%d\n", jiechen( i ) );

}

运行

输入3

结果为

1 ! = 1

2 ! = 2

3 ! = 3

静态内存、动态内存与堆栈

一、何谓静态内存、动态内存

静态内存分配好后,程序运行过程中一直存在不会被释放,且一旦分配好,其内存大小就固定下来不能改变,在编译和链接的阶段就会分配好。

动态内存是程序运行过程中,根据程序的需要分配和释放,其大小可变。

二、堆与栈

堆和栈都是动态分配的,区别有两点:

1、栈是由编译器分配与释放,堆是程序通过调用malloc或new分配,调用free 或delete释放。

2、栈是线性结构,堆是链表结构。

三、使用场景

1、全局变量和static修饰的静态变量都存放在静态内存区。

2、函数内部定义的局部变量,存储在栈上,函数退出时,其占用内存被收回。

3、通过调用malloc或new得到的内存在堆上,不再需要时要显示的调用free 或delete来释放,否则会造成内存泄漏,虽然有些操作系统会在程序退出后自动回收这部分内存,但还是要记住申请内存与释放内存成对操作,养成好习惯。

下面一段代码列举静态内存和动态内存的各种情形:

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"优化成一个地方。

}

相关文档
最新文档