动态数组

来源:互联网 发布:手机定位模拟软件 编辑:程序博客网 时间:2024/04/29 07:56

       在做上一个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);

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 支付宝账户名忘记了怎么办 搜索qq号搜不到怎么办 微信号手机号码换了怎么办 起诉以后没有被告人住址怎么办 农村老人走丢了怎么办 读在职博士工作单位不支持怎么办 两证合一后国税怎么办 杭州的发票丢了怎么办 小车登记证丢了怎么办 个体户地税逾期未申报怎么办 公司社保本丢了怎么办 社保红本子掉了怎么办 三证合一后逾期怎么办 个体执照没办国税地税怎么办 丰巢APP注册没工牌号怎么办 农业银行k宝证书过期怎么办 个体户网上申报税没定期怎么办 遇到不给开票的商户怎么办 奶茶店电脑下单怎么办 个体户营业执照注销怎么办清税业务 注册公司没有办公地点怎么办 变更莒业执照法人怎么办手续 欠了几十万贷款怎么办 杭州公司跨区迁址怎么办 公司同市内跨区迁址怎么办 合同写错了字怎么办 农行卡转工行卡怎么办 外地人在北京交社保退休怎么办 身份证掉了单位宿舍怎么办居住证 广州租住单位宿舍怎么办居住证 公司u盾丢了怎么办 北京办了居住卡怎么办延期 商铺被陌生人注册左公司怎么办 营业执照年检登录密码忘了怎么办 欠人家钱没钱还怎么办 欠钱实在没钱还怎么办 党关系丢了10年怎么办? 离婚后生孩子怎么办出生证明 注册公司没有注册地址怎么办 银行流水不够2倍怎么办 个体户小店怎么办五险