在阅读教程后,我采用了一种使用malloc
创建2-D
阵列的方法。但令我惊讶的是,用许多变体更改分配代码,得到了相同的输出。
考虑:
#include<stdio.h>
#include<conio.h>
void main()
{
int **ptr;
int row=3,col=5,i,j;
*ptr=(int **) malloc(sizeof(int *));
for(i=0;i<3;i++)
{
ptr[i]=(int *) malloc(sizeof(int )*col);
}
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
ptr[i][j]=1;
}
}
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
printf("val %d",ptr[i][j]);
free(ptr[i][j]);
}
printf("n");
}
free(ptr);
getch();
}
(对不起一个旧的编译器turbc 3,这是强制性的)
当语句:
*ptr=(int **) malloc(row*col*sizeof(int *));
更改为
*ptr=(int **) malloc(sizeof(int *));
或
*ptr=(int *) malloc(sizeof(int *));
或
*ptr=(int ) malloc(sizeof(int *));
或
*ptr=(int **) malloc(row*sizeof(int *));
给我一个相同的输出,那就是一个3*4
的数组,所有的都是1。
为什么是这样?
为了提高效率,malloc
通常会分配一个"最小空间块"。这可能是16个字节,或者更多,具体取决于编译器。我认为你"意外"得到了一个足够大的块——能够看到12点——而不会出错。但是您的代码是高度可疑的,并且随时可能被破坏。
正如@H2CO3所指出的,不要强制转换malloc
的返回值:如果你的编译器抱怨你没有包含正确的头。始终注意编译器的警告,但要以正确的方式处理它们。。。
注意,不是malloc
给了你一个一的数组,这是后面循环的工作。malloc
留出一些空间。如果它留出足够的空间,你就不会遇到segfault。它不会影响编译器随后如何考虑该内存。换句话说,malloc
不知道它返回什么(这就是为什么类型实际上是void*
,并且不应该强制转换它)。
编辑您询问了您选择的不同选角。强制转换不会更改VALUE,只更改TYPE(只要值可以用新类型表示)。因此,当你说时
int* p;
p = (int **)malloc(4);
你并没有把p
变成int**
——它的类型是由第一行定义的。您将(或应该)收到一些编译器警告。。。
Malloc根据您指定的大小分配一个空间。但是,当您复制一些character时,如果RAM
上有足够的位置,即使您指定了比要复制的字符串更小的大小,它也会起作用。在另一种情况下,它将打印随机字符,或者Glibc-内存损坏。所以,即使所有这些malloc定义都有效,也许它"暂时"在你的电脑上有效。但在另一种情况下,在其他情况下根本不会。此外,Glibc是危险的。