C/C++程序设计——动态内存

一、动态内存的概念

在使用数组的时候,总有一个问题困扰着我们:数组应该有多大?

例如编写程序求N阶行列式的值,用数组表示行列式,需如下定义:
        #define N 10    //数组定义时方括号内必须是常量
        double A[N][N]; //N*N二维数组表示二阶行列式

而以下定义形式则是错误的:(C++在CodeBlocks下无此问题)
int N;
scanf("%d",&N);     //输入N值
double A[N][N]={12};//意图由输入N值确定数组大小
    在很多情况下,并不知道实际运行时数组到底有多大,那么就要把数组定义得足够大,并且运行时要对下标做限制。否则,当定义的数组不够大时可能引起数组越界,导致严重错误。如果因为某种特殊原因对数组的大小有增加或减少,则 必须去重新修改和编译程序。之所以出现这样的问题是因为静态内存分配。
    C语言内存分配有两种方式:静态分配和动态分配。
    静态分配:在编译时为程序中的数据对象分配相应的存储空间。例如程序中所有的全局变量和静态变量,函数中的非静态局部变量等。由于是在编译时为数据对象分配存储空间,因此就要求在编译时空间大小是明确的,所以数组的长度必须是常量。而一旦编译完成,数组的长度在运行期间就是固定的。
    动态内存:程序运行期间根据实际需要动态地申请或释放内存的方式,不需要预先分配存储空间,而是根据程序的需要适时分配,且分配的大小就是程序要求的大小。
    静态分配的内存在程序内存布局的数据区和栈区中,动态分配的内存在程序的堆区中。堆区的存储空间的上限是物理内存的上限,因此动态内存分配可以得到比静态内存分配更大的内存空间。
    动态内存的缺点是运行效率不如静态分配,因为动态内存的分配和释放会产生额外的调用开销。在实际编程中,在运行时分配或内存大小需要随时调整等情况下才使用。

二、动态内存的分配与释放

C语言动态内存管理通过标准库函数实现,头文件为:stdlib.h
1.动态内存分配函数
(1)malloc函数:分配一个指定大小的内存空间
     函数原型: void *malloc(size_t size);
 若分配成功,则返回一个指向该内存空间起始地址的void型指针;若分配失败,则返回0值指针NULL。
*在实际编程中,malloc函数返回的void类型指针可以显式转换为其他指针类型。
*调用函数时,一般使用sizeof计算内存空间大小。
*需要注意,分配得到的内存空间是未初始化的。
例如:分配一个int型内存空间
int *p;
p=(int *)malloc(sizeof(int));
    若分配成功,p指向分配得到的内存单元,*p表示该内存单元。显然,动态内存分配得到的存储空间要按指针方式访问。一般情况下p值不能改变,否则该内存单元的起始地址就“永远是个谜”。
    分配失败的主要原因是没有足够的内存空间,所以在内存分配后,要检查返回值,确保指针是否有效。
if(p!=NULL)
{
;//引用*p;
}
(2)calloc函数:分配n个连续指定大小的内存空间
     函数原型: void *calloc(size_t nmemb,size_t size);
例如:分配50个int型内存空间
int *p;
p=(int *)calloc(50,sizeof(int));//等价于p=(int *)malloc(50*sizeof(int));
2.动态内存调整函数
  recalloc函数:调整已分配内存空间大小
  函数原型:void *realloc(void *ptr,size_t size);
3.动态内存释放函数
  free函数:释放动态分配的内存空间
  函数原型:void free(void *ptr);
  参数指针ptr指向已有的动态内存空间。
        int *p;
p=(int *)malloc(sizeof(int));
if(p!=NULL)
{
;//引用*p;
}
free(p);//释放p指向的内存空间,指针p变成迷途指针
p=NULL;//避免产生“迷途指针”

三、动态内存的应用

    动态内存不同于静态内存,在实际编程中应注意以下几点:

(1)静态内存管理由编译器进行,程序员只做对象定义(相当于分配);而动态内存管理按程序员的指令进行。

(2)动态内存分配和释放必须对应,即有分配必须有释放,不释放内存会产生内存泄露,后果是随着程序运行多次,可以使用的内存空间越来越小;另一方面,再一次释放已经释放的内存空间会导致程序出现崩溃性错误。

(3)静态分配内存的生命期由编译器自动确定,要么是程序运行期,要么是函数执行期。动态分配的内存生命期由程序员决定,即从分配开始,至释放结束。特别地,动态分配的内存的生命期可以跨多个函数。

(4)静态分配内存的对象有初始化,动态分配内存一般需要人为指令赋初始值。

(5)避免释放内存后出现“迷途指针”,应及时设置为空指针。   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值