Используйте 2D указатель без выделения - PullRequest
0 голосов
/ 19 января 2019

В следующем коде C я выделяю, инициализирую и определяю значения для **c. Я хочу, чтобы **assign принял значения **c. Но я объявляю только 2D-указатель для **assign, без выделения памяти, и код успешно выполняется и выводит те же результаты, что и **c. Не знаю почему?

int main(){

    int i,j;
    float **c=NULL, **assign=NULL;
    c = (float **)calloc(2,sizeof(float *));
    for (i=0;i<2;i++){
        c[i] = (float *)calloc(3,sizeof(float));
    }

    for (i=0;i<2;i++){
        for (j=0;j<3;j++){
            c[i][j] = i+j;
            printf("c[%d][%d]=%f\n",i,j,c[i][j]);
        }
    }

    assign = c;
    for (i=0;i<2;i++){
        for (j=0;j<3;j++){
            printf("assign[%d][%d]=%f\n",i,j,assign[i][j]);
        }
    }

    return 0;
}

1 Ответ

0 голосов
/ 19 января 2019

Указатель - это просто обычная переменная, которая содержит адрес чего-то другого в качестве значения. Другими словами, указатель указывает на адрес, где можно найти что-то еще.

Когда вы выделяете:

c = calloc(2,sizeof(float *));

Вы назначаете начальный адрес для нового блока памяти на c. Другими словами c указывает на место в памяти, где находятся первые (из двух) указателей, которые вы выделили.

При назначении (глагол):

assign = c;

Вы устанавливаете значение, удерживаемое assign, на значение, удерживаемое c. (и что держит c - адрес блока памяти, выделенного вам calloc). Таким образом, assign теперь содержит тот же адрес, что и c, например, assign теперь указывает на первый (из двух) указателей, которые вы выделили. Так что assign и c теперь оба содержат тот же адрес, что и их значение, и вы можете использовать любой из них для ссылки на то, что там хранится.

примечание: нет необходимости разыгрывать возврат malloc, это не нужно. Смотрите: Я разыграю результат malloc? . Кроме того, если вы используете разыменованный указатель для установки type-size для выделения, вы исключаете возможность ошибочного определения, например,

c = calloc (2, sizeof *c);
...