1. 程式人生 > >動態申請三維陣列

動態申請三維陣列

看了多維陣列和多維指標的 知識 ,就動手寫下  一些 bug 方便以後複習。

這是下linux 下用gcc 編譯的程式:
#include<stdio.h>
#include<malloc.h>
int*** dy3d(int high,int row,int colu)
{
	int i, j;

	int ***p1=(int***)malloc(sizeof(int**)*high);
	int **p2=(int**)malloc(sizeof(int*)*row*high);
	int *p3=(int*)malloc(sizeof(int)*high*row*colu);
	 //p=temp;

	for(i=0;i<high;i++)	
	{
	    //*(p1+i)=(p2+row*colu*i);
	    *(p1+i)=(p2+row*i);
	    for(j=0;j<row;j++)
	    {
		*(*(p1+i)+j)=(p3+colu*i);
		//*(p2+j)=(p3+colu*i);
	    }
	}
	
	return p1;
}

void free3d(int***p)
{
	if(**p!=NULL)
	{
		free(**p);	
		printf("free3\n");
	}
	if(*p!=NULL)
	{
		free(*p);	
		printf("free2\n");
	}
	free(p);
	printf("free1\n");
	return ;
}
int main()
{
	int ***p;
	int i,j,k;
	p=dy3d(50,3,3);
	for(k=0;k<50;k++)
	{
		   for(i=0; i<3; i++)
		  {
		      for(j=0; j<3; j++)
		      {
		          printf("%d, ", p[k][i][j]);
		      }
		      
		     // printf("\n");
		  }
			 printf("\n");
	}
	printf("sizeof(int**)==%d\n",sizeof(int**));
	free3d(p);
	return 0;
}

分析一下上面的程式: 這個程式也不是一下就寫成的 中間寫的版本 執行是會出現斷錯誤 所以 還是記錄一下下1.為什麼會想到用三維指標呢因為二維陣列 的表示可以用可以 二維指標表示:例二維陣列的陣列名可以看做是 指標常量 其指向的型別是 型別相同的一維陣列int a[3][3] 在遍歷的時候用 for 迴圈 可以寫作 :*( *(a+i)+j )==a[i][j] --->這裡解釋一下等式左邊 *(a+i) ---->得到的是一維陣列的陣列名(一維陣列的陣列名也可以看做 指標常量)--指標運算---> *(a+i)+j-->得到的還是地址*( *(a+i)+j )-- 獲取一維數組裡面的值這樣看三維陣列就應該是這樣的:int a[1][2][3] 遍歷的時候:

*(*( *(a+i)+j) +k) *(a+i) ---->得到的是2維陣列的陣列名(2維陣列的陣列名也可以看做 指標常量)--指標運算---> *(a+i)+j-->得到的還是地址*( *(a+i)+j )-- 獲取2維數組裡面的值即一維陣列的陣列名----->*(*( *(a+i)+j) +k) 得到一維數組裡的值這麼看的話自然應該用三維指標 。2.看到free3d(int***p)這個函式 ,引數只有一個三維指標,所以該三維指標的每一層都應該被賦予 恰當的值=====>指向合適的內出地址所以就能看到在 dy3d() 這個函式裡,p1 每一層 都指向合適的由malloc申請的地址空間在寫 *(p1+i)=(p2+row*i); 這個語句的時候有點疑惑 到底是用 *(p1+i)=(p2+row*colu*i); or *(p1+i)=(p2+row*i); 執行程式都是正常的,並不會出現段錯誤----------哎 這就疑惑了-------解惑:指標運算:

(p2+row*colu*i) 和 (p2+row*i) 都是指標運算當三維陣列的 (p1+i) 其實是指向 下一個同類型的二維陣列 (p2+row*i) 動態申請的時候 有多少個同類型的2維陣列 是row*high 所以row*i 就是第i個二維數值的地址值 --不會超過 2維指標申請的空間(p2+row*colu*i) 而這個值 是我單純的想到了 指標的跨度====忽略了 p2的指標型別 ==這個值也會明顯操出 所申請的二維指標區域