我正在阅读关于2D数组的动态内存分配,我正在看这个例子:
int nrows = 2;
int ncols = 5;
char **pvowels = malloc(nrows * sizeof(char));
pvowels[0] = malloc(ncols * sizeof(char));
pvowels[1] = malloc(ncols * sizeof(char));
我的理解是第二个和第三个malloc都分配了5个字符和pvowels [0]以及pvowels [1]指向每个内存的大小,但是我无法理解第一个malloc。
第一个malloc看起来像是分配2个字符大小的内存,并使用它来存储两个指针。但是不是char只有256个可能的值,指针可以达到数十亿?因此,如果它为存储指针分配内存,是不是需要比字符大?
答案 0 :(得分:4)
首先,您的第一个malloc()
不正确。使用nrows * sizeof(char)
仅分配2个字节,而您需要2行char*
个指针。你必须这样分配:
char **pvowels = malloc(nrows * sizeof(char*));
或者:
char **pvowels = malloc(nrows * sizeof(*pvowels));
另请注意,char **pvowels
不是一个2D数组,而只是指向char
指针的指针。如果您使用的是二维数组,例如char pvowels[][]
,则不需要在堆上动态分配指针。你也可以只为你的问题使用2D数组,例如char pvowels[2][5]
,ncols
和nrows
似乎在这种情况下是固定的。
其次,您对pvowels[0]
和pvowels[1]
的分配只会为4个有效字符留出空间,例如"abcd"
,因为空终止字符{{1}需要1个空格}。你应该写:
\0
注意: pvowels[0] = malloc(ncols+1); /* +1 for '\0' */
pvowels[1] = malloc(ncols+1);
始终为1,因此不需要包含它。您还应该检查sizeof(char)
是否已返回malloc()
。
答案 1 :(得分:2)
分配nrows
指向char
的{{1}}指针,然后单独分配nrows
ncols
char
个数组,这样做有一个缺点,那就是单独的内存分配不保证在内存中是连续的。这种分裂会导致性能下降。
更好的方法是分配足够的内存来容纳2d数组,并将结果指针指向指向ncols
char
s数组的指针。如图所示,这种方法确实依赖于VLA,但是自C99以来这些已成为C的一部分。这样做的好处是可以一次分配内存,只需要一次分配即可。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
size_t nrows = 2;
size_t ncols = 5;
/* Allocate space for a 2d array */
char (*pvowels)[ncols] = malloc(sizeof (char[nrows][ncols]));
/* Another alternative */
// char (*pvowels)[ncols] = malloc(nrows * ncols);
if (pvowels == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(EXIT_FAILURE);
}
for (size_t i = 0; i < nrows; i++) {
for (size_t j = 0; j < ncols; j++) {
pvowels[i][j] = 'a' + i * ncols + j;
}
}
for (size_t i = 0; i < nrows; i++) {
for (size_t j = 0; j < ncols; j++) {
printf("%5c", pvowels[i][j]);
}
putchar('\n');
}
free(pvowels);
return 0;
}
节目输出:
a b c d e
f g h i j
答案 2 :(得分:1)
char ** pvowels是一个指向指针的指针,这意味着它的行为就像一个声明如下的数组: char * pvowels [数字]; 所以基本上,在你提供的例子中,指向了chars而不是指针。
答案 3 :(得分:0)
简单易懂的代码:(仅使用一个指针来存储和访问)
#include<stdio.h>
#include<stdlib.h>
int main(){
int *a,n,r,c,i,j;
scanf("%d",&n);
r=c=n;
a=(int *)malloc(r*c*sizeof(int));
for(i=0;i<r;i++)
{
for(j=0;j<c;j++){
scanf("%d",(a+i*c+j));
}
}
for(i=0;i<r;i++)
{
for(j=0;j<c;j++){
printf("%d",*(a+i*c+j));
}
}
}
参考文献:geeksforgeeks.org