2d массив с использованием двойного указателя и функции malloc - PullRequest
2 голосов
/ 24 августа 2011

я пытаюсь создать 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));
    }

}

так как я объявил двойной указатель (** p1) для него, и я могу поместить данные во все эти места, используя мой оператор сканирования scanf("%d",(p1+i)+j);.И для разыменования я могу использовать оператор print, как я сделал printf("%d\n",*(*(p1+i)+j));

, но почему он ломается во время оператора print, но принимает мой оператор сканирования.

, но почему это дает мне правильный ответ...

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

Ответы [ 4 ]

4 голосов
/ 24 августа 2011

Ваша часть scanf реализована неправильно. Это уничтожает ваши данные. По иронии судьбы, проблема не проявляется во время фазы scanf, но вместо этого вызывает сбой на стадии printf.

Правильный код 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);
    }
}

Обратите внимание на дополнительные *. Что вам действительно нужно здесь, это

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

Вы можете написать это так, если хотите. Но вы можете заметить, что внешний & «аннигилирует» со следующим вложенным *, поэтому вышеприведенное эквивалентно

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

Однако я советую вам прекратить использовать едва читаемую комбинацию *-and-+ для доступа к элементу массива и вместо этого начать использовать []. Так должен выглядеть ваш код с самого начала

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

Кроме того, поскольку это помечено буквой C, избегайте использования sizeof с максимально возможным количеством типов и прекратите приведение результата malloc. Лучшим вариантом будет

int **p1;

p1 = malloc(2 * sizeof *p1);
for(int i = 0; i<2; i++)
{
  p1[i] = malloc(3 * sizeof *p1[i]);
  ...   
2 голосов
/ 24 августа 2011
scanf("%d",(p1+i)+j);

Это неправильно, а не то, что вы ожидаете.Ассоциативность говорит, что a + b + c == (a + b) + c == a + (b + c).

Избегайте арифметики с прямым указателем, потому что это плохо, когда вы новичок в языке.Предпочтение:

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

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

Сгенерированный код сборки точно такой же, как если бы вы использовали арифметику с прямым указателем.

Кроме того, независимо, но важно, не приводите тип возврата malloc (), поскольку это может скрывать потенциальные ошибки в вашем коде (например, отсутствие #include <stdlib.h>, что очень важно).


Имейте в виду, что типы int** и int[][N] довольноотличается в их реализации.Предположения, сделанные для одного, не верны для другого, даже если вы можете получить доступ к элементам, используя тот же синтаксис var[i][j].

Ваш второй пример дает правильный ответ, потому что он ... правильный?Вот и все.Во втором примере нет функции scanf (), и именно здесь ваша проблема в первом примере.

0 голосов
/ 11 сентября 2013
scanf("%d\n",(*(p1+i)+j));

замените ваш scanf на получение значений массива ...

0 голосов
/ 24 августа 2011

Создает двумерный массив, в котором все данные хранятся в соседних ячейках памяти в куче (в отличие от синтаксиса **, который чаще всего встречается).Он использует концепцию указателей массива , о которой вы можете прочитать в C lang FAQ .

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

И да, вы можете использовать ptr [x][y] если ты так малок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...