Двойной указатель - получение неожиданного вывода - PullRequest
0 голосов
/ 31 октября 2019
#include <stdio.h> 
#include <stdlib.h> 

int main()
{
    int a[3][3]={{0,1},{2,3},{5,6}},**b,i,j;
    b=(int **)calloc(3,sizeof(int *));
    for(i=0;i<3;i++)
    {
        b[i]=(int *)calloc(3,sizeof(int));
    }
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            b[i][j]=(i+1)*(j+1);
        }
    }

    printf("%d %d %d %d\n",*(*a+4),**a+4,*(*b+4),**b+4); 
    printf("%d %d %d %d\n",*(a[2]-2),**(a+2),*(b[2]-2),**(b+2)); 

    return 0;
}

Вывод, который я получаю:

3 4 2 5
3 5 6 3

По мне, я должен получить:

3 4 4 5
3 5 4 3

Причина:

*(*b+4) = *(b[0]+4). b[0]+4 указывает на b[1][1], поэтому это значение должно быть 4, что является значением матрицы в 1,1 позиции

*(b[2]-2), теперь b[2]-2 указывает на b[1][1], поэтому значениеснова должно быть 4

скажите, пожалуйста, почему я получаю другой вывод

1 Ответ

1 голос
/ 31 октября 2019

Когда вы объявляете двумерный массив, такой как a[3][3], весь массив является смежным, поэтому за a[0][2] сразу следует a[1][0]. Когда вы используете арифметику указателей на a, вы можете зависеть от этой способности пересекать строки, пока вы остаетесь в пределах всего массива a.

Но когда вы используете массив указателей, нетпричина ожидать, что каждый ряд будет смежным с предыдущим рядом. Память, выделенная каждому вызову на malloc(), не связана с предыдущими вызовами. Кроме того, malloc() должен гарантировать, что память правильно выровнена для любого типа данных;если размер, который вы выделяете, не кратен этому, они не могут быть смежными. И многие распределители динамической памяти хранят бухгалтерскую информацию (например, размер выделения, так что free() знает, сколько памяти требуется восстановить) перед выделением, что также предотвращает смежные выделения.

Это не определеноповедение для доступа к памяти за пределами размера выделения. Поскольку b[0] указывает на выделение 3 int, b[0]+4 находится за пределами этого выделения, а *(b[0]+4) вызывает неопределенное поведение.

...