动态数组

       在做上一个acm编程习题的时候其实就考虑过动态数组的问题,只是后来没有用,所以就把它给忘了,不料做到下一个练习的时候,真的还得用到动态数组,在vs2008中是不允许先定义一个变量,然后利用这个变量动态的定义数组的,我们只能使用malloc()内存管理函数。

       为什么要使用动态数组呢?在编程的的过程中,往往会出现这样一种情况:事先我们不知道究竟需要多大的内存空间,只有当输入一定的值之后我们才知道究竟需要多大的内存,这时候就需要动态数组。

       在使用动态数组中需要注意的一点是:由于使用到了malloc()函数,所以在使用完数组之后需要释放内存,否则造成内存泄露。

       动态数组遵循的原则是:

       申请的时候从外层想里层,逐层申请,释放的时候从里层向外层,逐层释放。

其实在1001题中已经使用到了动态数组,只不过那里的数组是一个意味的,在acm练习题1002中使用到的数组是二维的。(这部分的内容主要来源于百度百科)】

 

函数原型
返 回
功能说明
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);

 

这里面需要注意的有一下几点:

1、void*并不是代表着函数没有返回值,而是代表着函数的返回值是一个指针,而是返回值是一个节点的地址,该地址的类型是void,表示无类型或者类型是不确定的,即只是知道它返回的是一段存储区的首地址,而它具体的类型是无法确定的,只有在使用的时候根据各个域的具体值来确定。可以根据强制转换的方法将其转换成为别的类型

2、使用sizeof的目的是用来计算一种类型所占的字节数,以适应不同的编译器

3、由于动态分配不一定成功,为此需要附加一段异常处理程序,通常情况下的异常处理程序如下:

if(p==NULL)

{

       printf(“动态申请内存失败!\n”);

       exit(1);

}

说到这里了,我们顺便说一下exit(0)和exit(1),exit(1)表示的是异常退出,1是返回给操作系统的,exit(0)表示的是正常的退出。一般情况下,0表示的是正常,其他的数字表示的是异常退出,可以自己定义。

4、分配的堆空间是没有名字的,只能通过返回的指针找到它

5、只有动态分配的内存块才能使用free,也不能对同一个内存块free()两次

 

malloc()和calloc()函数的区别:

对于malloc分配的内存空间,如果原来没有被使用过的话,其中的每一个可能都是0,反之,如果这部分内存空间曾经被分配,释放和重新分配的话,那么其中可能会遗留各种各样的数据,因此在使用malloc函数的时候必须将申请到的函数进行初始化(可以memset),但是使用calloc()函数的时候,在分配的时候已经全部初始化为0了

具体的分配方法如下:

现在以3维整形数组为例:

array{n1][n2][n3]为例

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

所以:array=int(***)calloc(n1,sizeof(int**));

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

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

{

         array[i]=(int**)calloc(n2,sizeof(int*));

}

最内层的指针是array[][],它是一个一维的指针,指向的是array[][][],其实是一个整形变量,所以给array[][]申请内存应该是:

for(i=0;i<n:i++)

{

     for(j=0;j<2;j++)

      {

                  array[i][j]=(int *)calloc(n3,sizeof(int));

      }

 

}

当然也可以把他们放到一起:

 

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<n1;i++)
{
array[i]=(int**) calloc(n2,sizeof(int*));
for(j=0;j<n2;j++)
{
array[i][j]=(int*) calloc(n3,sizeof(int));
for(k=0;k<n3;k++)
{
array[i][j][k]=i+j+k+1;
}
}
}
当然和提到的上面的规则一样,在最后要释放申请的内存,下面值写出释放的代码:
for(i=0;i<n1;i++)
{
       for(j=0;j<n2;j++)
       {
                    freearray[i][j];
        }
}
for(i=1;i<n1;i++)
{
        free(array[i]);
}
free(array);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值