C 语言动态数组

在实际的编程中,往往会发生这种情况,即所需的内存空间取决于实际输入的数据,而无法预先确定。对于这种问题,用静态数组的办法很难解决。为了解决上述问题,C语言提供了一些内存管理函数,这些内存管理函数结合指针可以按需要动态地分配内存空间,来构建动态数组,也可把不再使用的空间回收待用,为有效地利用内存资源提供了手段。

动态数组,是相对于静态数组而言。静态数组的长度是预先定义好的,在整个程序中,一旦给定大小后就无法改变。而动态数组则不然,它可以随程序需要而重新指定大小。动态数组的内存空间是从堆(heap)上分配(即动态分配)的。是通过执行代码而为其分配存储空间。当程序执行到这些语句时,才为其分配。程序员自己负责释放内存。

为什么要使用动态数组?

在实际的编程中,往往会发生这种情况,即所需的内存空间取决于实际输入的数据,而无法预先确定。对于这种问题,用静态数组的办法很难解决。为了解决上述问题,C语言提供了一些内存管理函数,这些内存管理函数结合指针可以按需要动态地分配内存空间,来构建动态数组,也可把不再使用的空间回收待用,为有效地利用内存资源提供了手段。

动态数组与静态数组的对比

对于静态数组,其创建非常方便,使用完也无需释放,要引用也简单,但是创建后无法改变其大小是其致命弱点!

对于动态数组,其创建麻烦,使用完必须由程序员自己释放,否则严重会引起内存泄露。但其使用非常灵活,能根据程序需要动态分配大小。

如何构建动态数组

遵循原则

申请的时候从外层往里层,逐层申请;

释放的时候从里层往外层,逐层释放。

构建所需指针

对于构建一维动态数组,需要一维指针;

对于二维,则需要一维,二维指针;

三维需要一,二,三维指针;

依此类推。

构建所需函数

函数原型 返 回 功能说明
void *malloc(unsigned int size); 成功:返回所开辟
空间首地址  失败:返回空指针
向系统申请
size字节的
堆空间
void *calloc(unsigned int num,  unsigned int size); 成功:返回所开辟
空间首地址  失败:返回空指针
按类型申请
num个size字
节的堆空间
void free(void *p); 无返回值 释放p指向
的堆空间
void *realloc(void *p,unsigned int  size); 成功:返回新开辟
空间首地址  失败:返回空指针
将p指向的
堆空间变为
size

说明:

  • (1)规定为 void * 类型,这并不是说该函数调用后无返回值,而是返回一个结点的地址,该
    地址的类型为void(无类型或类型不确定),即一段存储区的首址,其具体类型无法确定,只有使
    用时根据各个域值数据再确定。可以用强制转换的方法将其转换为别的类型。例如:double
    *pd=NULL; pd=(double *)calloc(10,sizeof(double));  表示将向系统申请10个连续的
    double类型的存储空间,并用指针pd指向这个连续的空间的首地址。并且用(double)对calloc( )
    的返回类型进行转换,以便把double类型数据的地址赋值给指针pd。

  • (2)使用sizeof的目的是用来计算一种类型的占有的字节数,以便适合不同的编译器。

    (3)由于动态分配不一定成功,为此要附加一段异常处理程序,不致程序运行停止,使用户
    不知所措。通常采用这样的异常处理程序段:
    if(p==NULL) /* 或者if(!p)*/ { printf("动态申请内存失败!n"); exit(1); //异
    常退出 }

  • (4)这四个函数头文件均包含在中。

  • (5)分配的堆空间是没有名字的 只能通过返回的指针找到它。

  • (6)绝不能对非动态分配存储块使用free。也不能对同一块内存区同时用free释放两次。
    如:free(p);free(p);

  • (7)调用 free() 时, 传入指针指向的内存被释放, 但调用函数的指针值可能保持不变, 因
    为p是作为形参而传递给了函数。严格的讲, 被释放的指针值是无效的, 因为它已不再指向所申请
    的内存区。这时对它的任何使用便可能会可带来问题。

malloc与calloc的区别

对于用malloc分配的内存区间,如果原来没有被使用过,则其中的每一位可能都是0;反之,
如果这部分内存空间曾经被分配、释放和重新分配,则其中可能遗留各种各样的数据。也就是说,
使用malloc()函数的程序开始时(内存空间还没有被重新分配)能正常运行,但经过一段时间后(内
存空间已被重新分配)可能会出现问题,因此在使用它之前必须先进行初始化(可用memset函数
对其初始化为0),但调用calloc()函数分配到的空间在分配时就已经被初始化为0了。
当你在calloc()函数和malloc()函数之间作选择时,你需考虑是否要初始化所分配的内存空
间,从而来选择相应的函数。

具体构建方法

以三维整型数组array[n1][n2][n3]为例。

先遵循从外层到里层,逐层申请的原则:

最外层指针是array,它是个三维指针,所指向的是array[],其为二维指针。所以给array

申请内存应:

array=(int***)calloc(n1,sizeof(int**));

次层指针是array[],它是个二维指针,所指向的是array[][],其为一维指针。所以给array[]

申请内存应:

for(i=0;i

最内层指针是array[][],它是个一维指针,所指向的是array[][][],其是个整型常量。所以给array[][]申请内存应:

for(i=0;i

当然,你可以把它们整合在一起为:

int i,j,k;
int n1,n2,n3;
int ***array;
scanf("%d%d%d",&n1,&n2,&n3);
array=(int***)calloc(n1,sizeof(int**));
for(i=0;i

最后不要忘了释放这些内存,这要遵循释放的时候从里层往外层,逐层释放的原则。

分析过程可参考上面的解答,这里不再赘述。只给出代码吧:

for(i=0;i

其余维的如四维创建过程大同小异,这里不再赘述。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
  1. 免费下载或者VIP会员资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
  2. 提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。 若排除这种情况,可在对应资源底部留言,或联络我们。
  3. 找不到素材资源介绍文章里的示例图片?
    对于会员专享、整站源码、程序插件、网站模板、网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
  4. 付款后无法显示下载地址或者无法查看内容?
    如果您已经成功付款但是网站没有弹出成功提示,请联系站长提供付款信息为您处理
  5. 购买该资源后,可以退款吗?
    源码素材属于虚拟商品,具有可复制性,可传播性,一旦授予,不接受任何形式的退款、换货要求。请您在购买获取之前确认好 是您所需要的资源

评论(0)

提示:请文明发言