多维数组的动态分配
来源:互联网 发布:欧洲工商管理学院 知乎 编辑:程序博客网 时间:2024/05/25 19:59
方法一:内存不连续
假设数组元素的数据类型是int型,则动态分配二维数组的一般方法是这样:
int **p = NULL;
p = (int **)malloc(nWidth * sizeof(int *));
if (!p)
return NULL;
for (int j = 0; j < nWidth; j++)
{
p[j] = (int*)malloc(nHeight * sizeof(int))
if (!p[j])
return NULL;
}
-------------------------------------------------------
C++版本
int **p=NULL;
p=new int*[nWidth];
if (!p){
return NULL;
}
for (int j=0;j<nWidth;j++){
p[j]=new int[nHeight];
if (!p[j]){
return NULL;
}
}
-------------------------------------------------------
这段代码浅显易懂,先分配第1维,在循环分配第2维。假设二维数组是3×2的,每一句运行完后的内存情况如图所示(方格表示内存,xx表示随机数,方格下方是内存地址。当然,地址只是示意而已,与真实情况并不相符)
第一句完后分配了3个内存单元
循环分配后,注意下面3段内存通常是不连续的。这样用下表p[n][m]操作数组没问题,如果整块内存操作就会有问题了,比如下面这句:
原意是想把下面的3块6个内存单元清0,可是事与愿违,把从p开始后面6个内存单元清0了,p[]不能用了。p后面只有3个已分配的内存单元,却要操作6个,另外3个是未知区域。清了后面虚线的3块未知区域,这就很危险了,可能导致程序崩溃。
这样分配的内存需要循环释放。代码如下:
for (int j = 0; j < nWidth; j++)
{
free(p[j]);
p[j] = NULL;
}
free(p);
p = NULL;
方法二:内存连续
若要动态分配内存连续的二维数组,那么可以采用如下方法:
//p是一个指向指针的指针
int **p = NULL;
//请求系统分配一个包含nWidth个int*指针的空间,p指向空间的首地址。
//此空间用来作为二维数组的索引
p = (int **)malloc(nWidth * sizeof(int *));
if (!p)//若malloc失败
return NULL;
//请求系统分配一个包含nWidth*nHeight个int指针的空间,p[0]指向空间的首地址。
//此空间用来保存二维数组的数据
p[0] = (int *)malloc(nHeight * nWidth * sizeof(int));
if (!p[0])//若malloc失败
{
free(p);
return NULL;
}
//索引与相应数据的关联
for(int i = 1; i < nWidth; i++)
p[i] = p[i-1] + nHeight;//留意并思考此处为什么是直接加上nHeight的值
memset(p[0], 0, nHeight * nWidth*sizeof(int));//二维数组清零
这段代码解决了分配的空间不连续的问题。每一句运行完后的内存情况如图所示:
第一句和上面一样。
这6个内存单元是一次分配的,所以连续。
这个二维数组的数据首地址是p[0],p是第2维的索引首地址。所以如果要对二维数组进行整体的内存(缓冲区 buffer)操作,要以p[0]为操作对象的首地址。
到此,索引与对应的数据地址关联上了。这个二维数组既可以通过下表p[][]来操作,又可以操作缓冲区。操作缓冲区的函数比如memcpy,cfile的writehuge和readhuge使用起来很方便,省去了2次循环的麻烦。
至于释放,不必循环释放。因为malloc了2次,所以只需free两次就行了:
free(p[0]); //释放二维数组
p[0] = NULL;
free(p); //释放指针空间
p = NULL;
-------------------------------------------------------
C++ 版本
分配:
int **p=NULL;
p=new int *[nWidth];
if (!p){
return NULL;
}
p[0]=new int[nWidth*nHeight];
if (!p[0]){
delete[] p;
return NULL;
}
ZeroMemory(p[0],nWidth*nHeight*sizeof(int));
for (int i=1;i<nWidth;i++){
p[i]=p[i-1]+nHeight;
}
释放:
f(!p){
return;
}
delete []p[0];
p[0]=NULL;
delete[] p;
p=NULL;
-------------------------------------------------------
C++中静态二维数组和动态二维数组的区别
这里所说的静态二维数组,就是在程序中类似int b[2][20]定义的数组;所说的动态二维数组,就是在程序中通过int **a = new int*[2];
a[0] = new int[20]; a[1] = new int[20]声明的数组。( 二维数组的本质还是一维数组。静态二维数组的存储空间等同于单一的一维数组,而动态二维数组等同于多个一维数组的组合,每一个一维数组,等同于二维数组的一个行向量。)
静态二维数组放在系统内存的stack里,动态数组放在内存的heap里面。这个却别不是本文讨论的重点。这里要着重说明的是,静态数组的存储空间是个地址连续的内存区域,而动态分配的二维数组空间,非常可能是不连续的地址空间。
在Robert Sedgewick所著的Algorithm In C中,把二维数组当成数组的数组为它动态分配内存。
函数定义:
方法一:
当需要访问a[i][j]时,
当需要释放空间时,用如下方式访问:
方法二:
void **malloc2d(int row, int col, int size)
{
}
void free2d(void **arr)
{
}
最值得推荐的方法是方法二
参考资料:
http://hi.baidu.com/jiaon/item/52017c5a145debcfd2e10c52
http://hi.baidu.com/_forward001/blog/item/8a7a5f867095c63966096e59.html
http://topic.csdn.net/u/20081124/18/60e5259e-f1ae-4fe9-bda1-cd7b609250d8.html?seed=1045715561&r=60398843#r_60398843
http://hi.baidu.com/_forward001/blog/item/8a7a5f867095c63966096e59.html
http://topic.csdn.net/u/20081124/18/60e5259e-f1ae-4fe9-bda1-cd7b609250d8.html?seed=1045715561&r=60398843#r_60398843
http://blog.sina.com.cn/s/blog_700e74120100lmtd.html
- 多维数组的动态分配
- 多维数组的动态分配
- 多维数组的动态分配(二三维)
- c/c++ 多维数组的动态分配
- 如何动态分配多维数组
- 动态分配多维数组
- 动态分配多维数组
- 动态分配多维数组
- 动态分配多维数组
- 多维数组动态分配内存空间
- 二维数组的动态分配,可扩充成多维数组
- 纯c语言实现动态分配多维数组的方法
- 纯c语言实现动态分配多维数组的方法
- 7.13 我该如何动态分配多维数组 ?
- 我该如何动态分配多维数组?
- c/c++多维数组动态分配与释放
- 我该如何动态分配多维数组?
- C多维数组动态分配与释放
- nandflash的操作方法
- mysql用户管理
- JavaIO之输入输出流链(一)
- Single Number II - leetcode
- 《C++ Primer (5th Edition)》笔记-Part IV. Advanced Topics
- 多维数组的动态分配
- 剑指offer-33:把数组排成最小的数
- 怎么在你的网站应用中使用PHP和jQuery建立日历
- c++内存布局经典文章
- Java高级特性之系统可用编码(一)
- OpenStack 动态迁移流程分析
- TCP/IP网络层
- 一个简单线程池的实现
- hdu 4617 Weapon 计算异面直线间距离