c-二维阵列与malloc玩把戏



在阅读教程后,我采用了一种使用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是危险的。

相关内容

  • 没有找到相关文章

最新更新