现在的位置: 首页 > 综合 > 正文

C/C++中的二维指针问题

2013年10月14日 ⁄ 综合 ⁄ 共 2388字 ⁄ 字号 评论关闭

 

指针是可变数组的首地址。正因为是可变数组,所以一般使用指针时都是采用动态内存分配和释放的方式。一维指针形式简单,容易理解。平时应用较多。二维数组和二维指针比较复杂,并且在动态内存分配与释放方面比较复杂且难以理解。但是二维数组和二维指针是非常有用的。

     考虑以下应用:对一幅图像进行模板运算。这必然会牵涉到对图像的各象素点的操作。此时使用一维指针进行图像传递时,不可避免的会使用形如*(p+i*width+j)的方式完成对图像象素点的访问。这种方式很不直观并且编写程序时容易出错。如果使用二维指针进行图像数据的传递,则会收到很好的效果。可以采用p[i][j]的方式直接操作象素点,直观又便于维护。因此掌握二维数组和二维指针是必要的。

使用http://www.wangchao.net.cn/bbsdetail_59038.html中的示例。

定义如下3个二维数组和二维指针进行说明:

1.         int** ptr;

2.         int *ptr[M];

3.         int (*ptr)[M];

以上都是存放整数的二维数组,并且都可以通过ptr[i][j]的形式访问内容。但是它们之间有很大的差别。以下依照文中提到的方面进行分析。

l         内容
三个ptr本身都是指针,并且是二维指针,但是它们的最终内容总是整数。但中间内容,形如ptr[i]并不是整数,而是指针int
*.

l         意义
1. int** ptr 表示指向(一组指向整数数据指针)的指针;
2. int *ptr[M] 是指针数组,表示指向(M个指向整数指针)的指针;
3. int (*ptr)[M]表示指向一组(指向包含M个整型数据的指针)的指针。

l         所占空间
13占用一个内存空间,在32位平台上为4个字节,也就是一个指针。
2M个指针,在其定义过程中编译器即对其进行了分配,占用4*M4M个字节。

l         用法
1. int** ptr 表示指向(一组指向整数数据指针)的指针,是一个二维指针。在其定义过程中,编译器并不对其进行内存的分配,因此必须自己管理其内存的分配与释放。典型使用如下:

int** ptr;

int i,j;

ptr = (int**)malloc((sizeof(int*))*M); 

printf("The Address of ptr:%10x\n",ptr); 

for (i=0;i<M;i++)

{

       ptr[i] = (int*)malloc(sizeof(int)*N); 

         printf("The Address of ptr[%d]:%10x\n",i,ptr[i]); 

}

//采用如上内存分配方法,意味着将ptr初始化为M*N的二维数组首地址

//可以访问ptr[0:M-1][0:N-1]的数据

//操作

for (i=0;i<M;i++)

{

         free(ptr[i]); 

}

free(ptr);

使用上述方法分配内存,最终ptr耗费的内存空间为M*sizeof(int*)+M*N*sizeof(int)

2. int *ptr[M] 是指针数组,表示指向(M个指向整数指针)的指针。是一个二维指针。但是在定义的时候,编译器已经为ptr指向的M个指向整数的指针ptr[0:M-1]分配了内存。也就是说,定义之后即可得到ptr的地址以及用于存放ptr[0:M-1]的内存空间4MB。要使用ptr必须对ptr[i]分配内存。分配内存后,ptr地址相应内存空间填入ptr[i]指向内存地址。使用如下操作:

int* ptr[M]; 

int i,j; 

printf("The Address of ptr:%10x\n",ptr); 

for (i=0;i<M;i++)

{

         ptr[i] = (int*)malloc(sizeof(int)*M); 

         printf("The Address of ptr[%d]:%10x\n",i,ptr[i]); 

}

//采用如上内存分配方法,意味着将ptr初始化为M*N的二维数组首地址

//可以访问ptr[0:M-1][0:N-1]的数据

//操作

for (i=0;i<M;i++)

{

         free(ptr[i]); 

}

//free(ptr); //此处不释放ptr内存,是因为ptr的内存是由编译器分配的。

使用上述方法分配内存,最终ptr耗费的内存空间为M*sizeof(int*)+M*N*sizeof(int),其中M*sizeof(int*)为编译器分配,M*N*sizeof(int)为程序员自己分配。

3. int (*ptr)[M]表示指向一组(指向包含M个整型数据的指针)的指针。该定义限定了ptr[i][0:M-1],所有指针ptr[i]必须指向长度为M的数组。使用方式如下:

int (*ptr)[M]; 

int i,j; 

 

printf("The Address of ptr:%10x\n",ptr); 

ptr = (int (*)[M])malloc(sizeof(int)*M*N); //一次分配连续内存

printf("The Address of ptr:%10x\n",ptr); 

for (i=0;i<N;i++)

{

//      ptr[i] = (int [M])malloc(sizeof(int)*M); 

         printf("The Address of ptr[%d]:%10x\n",i,ptr[i]); 

}

//采用如上内存分配方法,意味着将ptr初始化为N*M的二维数组首地址

//可以访问ptr[0:N-1][0:M-1]的数据

//操作

free(ptr);

使用上述方法分配内存后,ptr所占内存空间为M*N*sizeof(int)(不考虑不同操作系统用于管理的内存)。ptr内存空间中保存的为最终内容而非ptr[i]地址。


抱歉!评论已关闭.