简体   繁体   English

使用双指针和malloc函数的二维数组

[英]2d array using a double pointer and malloc function

i am trying to create a 2d array using double pointer... my code is... 我正在尝试使用双指针创建2D数组...我的代码是...


int **p1;
p1=(int **) malloc(2*sizeof(int *));
for(int i=0;i<2;i++)
{
    p1[i]=(int *) malloc(3*sizeof(int));
    for(int j=0;j<3;j++)
    {
       scanf("%d",(p1+i)+j);
    }

}
for(int i=0;i<2;i++)
{

    for(int j=0;j<3;j++)
    {
       printf("%d\n",*(*(p1+i)+j));
    }

}

as i have declared a double pointer (**p1) for it and i am able to put data at all those places using my scan scanf("%d",(p1+i)+j); 因为我已经为其声明了双指针(** p1),并且能够使用扫描scanf("%d",(p1+i)+j);将数据放在所有这些位置scanf("%d",(p1+i)+j); statement. 声明。 And to dereference i can use print statement as i have done printf("%d\\n",*(*(p1+i)+j)); 要取消引用,我可以使用print语句,因为我已经完成了printf("%d\\n",*(*(p1+i)+j));

but why it is breaking during print statement but accepting my scan statement. 但是为什么它在打印语句期间中断但接受我的扫描语句。

but why this is giving me correct response... 但是为什么这给了我正确的答案...

int mybox[][4]={{1,2,3,4},{5,6,7,8}};//we have to provide subscript;
for(int i=0;i<2;i++){
     for(int j=0;j<4;j++){
        printf("%d",mybox[i][j]);//will print all elements
        }
}
        printf("%d",*(*(mybox)+1));//give me 2
        printf("%d",*(*(mybox+1)+1));//give me 6
        printf("%d",*(*(mybox+1)+3));//give me 8

Your scanf portion is implemented incorrectly. 您的scanf部分执行不正确。 It destroys your data. 它会破坏您的数据。 Ironically, the problem does not reveal itself during scanf phase, but instead causes a crash at printf stage. 具有讽刺意味的是,该问题并未在scanf阶段显示出来,而是在printf阶段导致崩溃。

The correct scanf code might look as follows 正确的scanf代码可能如下所示

for(int i=0;i<2;i++)
{
    p1[i]=(int *) malloc(3*sizeof(int));
    for(int j=0;j<3;j++)
    {
       scanf("%d",*(p1+i)+j);
    }
}

Note the extra * . 注意额外的* What you really need here is 您真正需要的是

scanf("%d", &(*(*(p1 + i)) + j));

You can write it this way if you want. 您可以根据需要以这种方式编写它。 But you can notice that the outer & "annihilates" with the next nested * , so the above is equivalent to 但是您会注意到,外部&与下一个嵌套* “歼灭”,因此上述等效于

scanf("%d", *(p1 + i) + j);

However, my advice to you is to stop using the barely-readable *-and-+ combination for array element access and start using the [] instead. 但是,我对您的建议是停止使用几乎不可读的*-and-+组合键访问数组元素,而开始使用[] This is how your code should have looked from the very beginning 这就是您的代码从一开始就应该具有的外观

...
scanf("%d", &p1[i][j]);
...
printf("%d\n", p1[i][j]);

On top of that, since this is taggged C, avoid using sizeof with types as much as possible and stop casting the result of malloc . 最重要的是,由于这是C标记,因此请避免将sizeof与类型一起使用,并停止转换malloc的结果。 A better variant would be 更好的变体是

int **p1;

p1 = malloc(2 * sizeof *p1);
for(int i = 0; i<2; i++)
{
  p1[i] = malloc(3 * sizeof *p1[i]);
  ...   
scanf("%d",(p1+i)+j);

This is wrong, and not what you expect. 这是错误的,不是您所期望的。 Associativity says that a+b+c == (a+b) + c == a + (b+c). 关联性表示a + b + c ==(a + b)+ c == a +(b + c)。

Avoid direct pointer arithmetic because it is hell confusing when you are new to the language. 避免使用直接指针算法,因为当您刚接触该语言时,它会令人困惑。 Prefer: 身高:

   scanf("%d", &p1[i][j]);

   printf("%d\n", p1[i][j]);

The generated assembly code is exactly the same as if you went for direct pointer arithmetic. 生成的汇编代码与您进行直接指针算术的完全相同。

Also, unrelated but important, do not cast the return type of malloc(), as this may hide potential bugs in your code (like the lack of a #include <stdlib.h> , which is very important). 另外,无关但重要的是,不要转换malloc()的返回类型,因为这可能会在代码中隐藏潜在的错误(例如缺少#include <stdlib.h> ,这非常重要)。


Keep in mind that the types int** and int[][N] are quite different in their implementation. 请记住,类型int**int[][N]在实现上完全不同。 Assumptions made for one are not true for the other, even though you can access the elements using the same var[i][j] syntax. 尽管可以使用相同的var[i][j]语法访问元素,但对另一个所做的假设并不正确。

Your second example gives the correct answer because it is... correct? 您的第二个示例给出了正确答案,因为它是...正确吗? That is it. 这就对了。 The second example doesn't have any scanf(), which is where your problem is in the first example. 第二个示例没有任何scanf(),这是第一个示例中的问题所在。

scanf("%d\n",(*(p1+i)+j));

替换您的scanf以获取数组值...

This creates a 2d array where all data is stored in adjacent memory cells on the heap (as opposed to the ** syntax more commonly seen). 这将创建一个2d数组,其中所有数据都存储在堆上的相邻存储单元中(与**语法相反)。 It uses the concept of array pointers which you can read about in the C lang FAQ . 它使用数组指针的概念,您可以在C lang FAQ中阅读有关数组指针的知识

int (*ptr)[X]; 
ptr = malloc(X * Y * sizeof(int));

And yes, you can use the ptr[x][y] if you malloc in this way. 是的,如果以这种方式进行malloc,则可以使用ptr [x] [y]。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM