user-0 提问: 用calloc函数分配的内存空间,怎样用二维数组的方式访问?

回复:
user: user-0
content: 引用int (*p)[20];  刚刚试了一下,赵4老师的这一句原来只占一个指针的空间,我以为像定义一个整数数组一样占20个元素的空间. 很好的代码啊,谢谢

user: user-0
content: [quote 你应该看赵4老师那个，那个才像是高手写的代码。  评价下：你这样做和数组定义int a[m][n];差不多，没能体现malloc()和calloc()动态分配内存的优势，因为中间数组容量不能变，而我一开始形式，就自由的多，更节省内存，缺点是在堆内存中，效率应该低点。[/quote]  谢谢,因为我本来只想定义一个指针p,当需要二维数组存放数据时就用calloc动态分配,不用的时候就free,这样保证程序运行时尽量少占用内存.赵4老师的方式很严谨简洁,不过因为我之前没说明只用一个指针p,而我实际程序中的m和n值都很大,所以int (*p)[20]这个方法在我程序中可能也需要一直占用很多内存  另外也谢谢赵4老师,这代码简洁漂亮,学习一下有不少收获.  结帖比较早,没想到后面又有回复,谢谢各位

user: user-1
content: 带斜杠那一行应该去掉。 去掉*(p + i) = (int*)calloc(n, sizeof(int));    //////

user: user-1
content: 你这样想，很有创意。 我认为你是这样想的：先连续分配m*n个连续空间，然后在内存中进行修改，这样确实保证了一维。但正确代码应该如下：  #include <stdio.h> #include <stdlib.h>  int main() { 	int m=10,n=20; 	int i,j,k; 	int *base = (int*)calloc(m*n, sizeof(int)); 	int **p = (int**)calloc(m, sizeof(int*)); 	for (i = 0; i < m; i++){ 		*(p + i) = (int*)calloc(n, sizeof(int));    //////	 		*(p + i)=&base[i*n]; 	} 	for (i = 0; i < m; i++){ 		for (j = 0; j < n; j++){ 			p[i][j]=m*i+j; 			printf("%d ", p[i][j]); 		} 		printf("\n"); 	} 	printf("\n"); 	int *p1 = &p[0][0]; 	for (i = 0,k=0; i < m*n; i++){ 		printf("%d ",*(p1+i)); 		k++; 		if (k >= n){ 			printf("\n"); 			k=0; 		} 	} 	free(p); 	getchar(); 	return 0; }   你应该看赵4老师那个，那个才像是高手写的代码。  评价下：你这样做和数组定义int a[m][n];差不多，没能体现malloc()和calloc()动态分配内存的优势，因为中间数组容量不能变，而我一开始形式，就自由的多，更节省内存，缺点是在堆内存中，效率应该低点。

user: user-2
content: #include <stdio.h> #include <stdlib.h> #include <malloc.h> int main() {     int m=10,n=20,y,x;     int (*p)[20];     p=(int (*)[20])calloc(m*n, sizeof(int));     if (!p) return 0;     for (y=0;y<m;y++) {         for (x=0;x<n;x++) {             p[y][x]=y*n+x;         }     }     for (y=0;y<m;y++) {         for (x=0;x<n;x++) {             printf("%4d",p[y][x]);         }         printf("\n");     }     free(p);     return 0; } //   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19 //  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39 //  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59 //  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79 //  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99 // 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 // 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 // 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 // 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 // 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 //

user: user-1
content: 我不知道，具体应涉及：malloc(),free(),calloc()等函数在内存上的管理，应该是堆区。 还没学底层的，不过我用函数调试了一下，不是连续分配的，而是隔了16个数，而且后面有些不同。有待继续思考学习，抱歉  另：刚才的代码有缺陷，分配内存后未能释放，改正。  #include <stdio.h> #include <stdlib.h>  int main() { 	int m=10,n=20; 	int i,j,k; 	int **p = (int**)calloc(m, sizeof(int*)); 	for (i = 0; i < m; i++){ 		*(p + i) = (int*)calloc(n, sizeof(int)); 	} 	for (i = 0; i < m; i++){ 		for (j = 0; j < n; j++){ 			p[i][j]=m*i+j; 			printf("%d ", p[i][j]); 		} 		printf("\n"); 	} 	printf("\n"); 	int *p1 = &p[0][0]; 	for (i = 0,k=0; i < m*n+16*m; i++){ 		printf("%d ",*(p1+i)); 		k++; 		if (k >= n){ 			printf("\n"); 			k=0; 		} 	} 	for (i = 0; i < m; i++) 		free(*(p + i)); 	free(p); 	getchar(); 	return 0; }   应学的更深，更全面，还是不够。

user: user-0
content: 引用 3 楼 liukeyong2110 的回复:这是很合理的想法，但你既然使用了**p，就应该为*p分配空间，即是设计旅馆，先分配楼，1-6楼，然后再为楼分配房间101-110，你只分配了房间，怎么分布呢？当然在具体存储时还是一维的，但你要用数组访问它，就需要这样： 参考代码： #include <stdio.h> #include <stdlib.h>  int main() { 	int m=10,n=20; 	int i,j; 	int **p = (int**)calloc(m, sizeof(int*)); 	for (i = 0; i < m; i++){ 		*(p + i) = (int*)calloc(n, sizeof(int)); 	} 	for (i = 0; i < m; i++){ 		for (j = 0; j < n; j++){ 			p[i][j]=m*i+j; 			printf("%d ", p[i][j]); 		} 		printf("\n"); 	} 	getchar(); 	return 0; }     谢谢指点,我明白了,因为我不知道多次调用calloc分配到的空间是否像正常定义二维数组那样连续,但是看了你的说明,我把你的代码有两行稍改一下,不知这样是否可行,请指教 int **p = (int**)calloc(m*n, sizeof(int*));	////  *(p + i) = (int*)(p+n);	//////   #include <stdio.h> #include <stdlib.h>  int main() {     int m=10,n=20;     int i,j;     int **p = (int**)calloc(m*n, sizeof(int*));	////     for (i = 0; i < m; i++) 	{         *(p + i) = (int*)(p+n);	//////     }     for (i = 0; i < m; i++){         for (j = 0; j < n; j++){             p[i][j]=m*i+j;             printf("%d ", p[i][j]);         }         printf("\n");     }     getchar();     return 0; }

user: user-0
content: 引用 3 楼 liukeyong2110 的回复:这是很合理的想法，但你既然使用了**p，就应该为*p分配空间，即是设计旅馆，先分配楼，1-6楼，然后再为楼分配房间101-110，你只分配了房间，怎么分布呢？当然在具体存储时还是一维的，但你要用数组访问它，就需要这样： 参考代码： #include <stdio.h> #include <stdlib.h>  int main() { 	int m=10,n=20; 	int i,j; 	int **p = (int**)calloc(m, sizeof(int*)); 	for (i = 0; i < m; i++){ 		*(p + i) = (int*)calloc(n, sizeof(int)); 	} 	for (i = 0; i < m; i++){ 		for (j = 0; j < n; j++){ 			p[i][j]=m*i+j; 			printf("%d ", p[i][j]); 		} 		printf("\n"); 	} 	getchar(); 	return 0; }   谢谢,请问这样多次调用calloc分配到的空间是连续的吗

user: user-0
content: 我实际程序中用到的二维数组比较大,用二维的方式是因为比较像表格的行列,这样写主要是考虑到代码的易读性,写的时候逻辑比较清晰,不易出错,另外正在学C,所以也想知道有没有什么简单的方法做到这一点

user: user-1
content: 这是很合理的想法，但你既然使用了**p，就应该为*p分配空间，即是设计旅馆，先分配楼，1-6楼，然后再为楼分配房间101-110，你只分配了房间，怎么分布呢？当然在具体存储时还是一维的，但你要用数组访问它，就需要这样： 参考代码： #include <stdio.h> #include <stdlib.h>  int main() { 	int m=10,n=20; 	int i,j; 	int **p = (int**)calloc(m, sizeof(int*)); 	for (i = 0; i < m; i++){ 		*(p + i) = (int*)calloc(n, sizeof(int)); 	} 	for (i = 0; i < m; i++){ 		for (j = 0; j < n; j++){ 			p[i][j]=m*i+j; 			printf("%d ", p[i][j]); 		} 		printf("\n"); 	} 	getchar(); 	return 0; }

user: user-3
content: int m=10,n=20,i; int** p; p=(int**)calloc(m, sizeof(int*)); for(i=0;i<m;++i)     p[i]=(int*)calloc(n,sizeof(int));或者int m=10,n=20; int *p=(int*)calloc(m*n,sizeof(int)); // 调用:p[i*n+j];0<=i<m,0<=j<n

user: user-4
content: C语言中的二维数组的本质是一维数组，都是按线性存放的，何苦要用p[i][j]的方式访问