二维指针的几个常见写法的区别,与空间的动态开辟讲解

来源:互联网 发布:视频无损分割软件 编辑:程序博客网 时间:2024/04/28 19:46

参考博客:http://c.360webcache.com/c?m=9db630237bcab162c751bfcb09608e76&q=calloc%E5%BC%80%E8%BE%9F%E4%BA%8C%E7%BB%B4%E6%95%B0%E7%BB%84&u=http%3A%2F%2Fwww.cnblogs.com%2Fpanglei%2Farticles%2F2288013.html
下面三种定义形式怎么理解?怎么动态分配空间?
(1)、int **Ptr;
(2)、int *Ptr[ 5 ];
(3)、int ( *Ptr )[ 5 ];
这三个都是二维指针,但是差别却是很大。
一、意义:
(1)、int **Ptr 表示指向”一群”指向整数的指针的指针,类似int[x][y]。
(2)、int *Ptr[ 5 ] 表示指向 5 个指向整数的指针的指针,这个就是指针数组,或者说Ptr有5个指向”一群”整数的指针,Ptr是这5个指针构成的数组的地址,类似int[5][x]
(3)、int ( *Ptr )[ 5 ] 表示指向”一群”指向 5 个整数数组的指针的指针,或则说ptr是指向一群数组指针的指针,*ptr,*ptr++,…….每个都是一个带有5个整形元素的数组指针,相当于int[x][5]。
其中x,y都是未知数,我相信这样讲解很多人基本都可以理解了
三、所占空间:
(1)、int **Ptr ,和int ( *Ptr )[ 5 ] 一样,本质上都是指针,在32位平台里,都是4字节,即一个指针。
但 (2)、int Ptr[ 5 ] 不同,是指针数组,它是 5 个指针,它占5 4 = 20 个字节的内存空间。
四、用法:这里主要讲解空间分配与释放。
(1)、int **Ptr
因为是指针的指针,需要两次内存分配才能使用其最终内容。首
先,Ptr = ( int * )new int [ 5 ];这样分配好了以后,它和(2)的
意义相同了;然后要分别对 5 个指针进行内存分配,
for(int i = 0;i < 5;i++)
{
ptr[i] = new int[10];
}
如果没有第一次内存分配,该 Ptr 是个”野”指针,是不能使用
的,如果没有第二次内存分配,则 Ptr[ i] 等也是个”野”指针,也
是不能用的。当然,用它指向某个已经定义的地址则是允许的,那是另外
的用法(类似于”借鸡生蛋”的做法),这里不作讨论(下同)。
空间释放:
for(int i = 0;i < 5;i++)
{
delete[]ptr[i]
}
delete[]ptr
换用calloc开辟:
int **a;
a=(int *)calloc(sizeof(int ),n);
for (i=0;i a[i]=(int *)calloc(sizeof(int),n);
这样就可以了
malloc同理
(2)、int *Ptr[ 5 ]
这样定义的话,编译器已经为它分配了 5 个指针的空间,这相当
于(1)中的第一次内存分配。根据对(1)的讨论可知,显然要对其进行一次
内存分配的。否则就是”野”指针。
(3)、int ( *Ptr )[ 5 ]
相当于里面的每个数组指针都已经开辟好了带有5个数组元素的空间,但是ptr还需要开辟空间。
Ptr = ( int ( * )[ 5 ] ) new int[ 5 * k ]。
这是一次性的内存分配。分配好以后,Ptr 指向一片连续的地址空间,
其中 Ptr[ 0 ] 指向第 0 个 5 个整数数组的首地址,Ptr[ 1 ] 指向第
1 个 5 个整数数组的首地址。

0 0