int M = 3, N = 3, G = 2;
	int***t=(int***)(malloc(sizeof(int**)*M));	
		for (int i = 0; i < M; i++)
		{
			t[i] = (int**)(malloc(sizeof(int*)*N));
			for (int a = 0; a < N; a++)
			{
				t[i][a] = (int*)(malloc(sizeof(int)*G));

			}
		}
	for (int i = 0; i < N; i++)
		for (int a = 0; a < M; a++)
			for (int k = 0; k < G; k++)
			{
				t[i][a][k] = i + a + k;
				printf("%d\n",t[i][a][k]);

			}

    不知道大脑缺了根啥筋,逻辑思维能力这么差

     

int M = 3, N = 3, G = 2;
	int***t=(int***)(malloc(sizeof(int**)*M));	//t为int***型,所以返回的类型时int***型,而每一个t所代表的地址里存放的类型为int**型,所以sizeof(int**),有多少个int**型要分配?肯定是M个,所以t要分配的地址是sizeof(int**)*M
		for (int i = 0; i < M; i++)//为什么这里是循环M次?t[i]的类型时int**型,有多少个int**需要动态分配内存呢?t[M],也就是M个。好,假如给t[1]分配内存,
		{
			t[i] = (int**)(malloc(sizeof(int*)*M));//这里为什么不是sizeof(int**)而是sizeof(int*)*M?设a=t[1],则a=t[][]因此实际上就和int***t=(int***)(malloc(sizeof(int**)*M));的思路一样了
//每一个a地址中存放的是一个int*型,而且存放了N个int*型 for (int a = 0; a < N; a++)//这里的思维误区就是t[1]代表的是什么,t[1]是一个地址,你给你一个地址分配内存并不是给这个地址本身分配内存,而是给这个地址中的东西到底占了多少字节分配内存。而sizeof[int**]是存放t[1]这个地址所要占的内存。 { t[i][a] = (int*)(malloc(sizeof(int)*G)); } }

  动态分配内存是一定要注意的误区:你要分配的内存不是存放地址本身所要分配的内存,而是在这个地址里面的东西,他们占了多少内存,我们就分配多少内存!!!这个就是sizeof(int**)和sizeof((int*)*N)的区别。sizeof(int**)只是存放t【i】这个地址所要占的内存,而给t[i]这个地址分配内存是要考虑t[i]这个地址里有什么,然后给里面的东西分配内存。

  总结:动态分配内存,第一点看变量所代表的地址里面存放的数据是什么类型,第二点看,地址里面这种类型有多少个。就OK了。