Почему данный вывод создается после запуска jumbleArrays ()? - PullRequest
0 голосов
/ 09 апреля 2019

У меня есть следующий код C:

int array_len(int *a) {
    int i;
    for(i = 0; i < ARRAY_SIZE && a[i] != TERMINATOR; i++);
    return i;
}

void jumbleArrays(int *a1, int *a2)
{
    int a1_len = array_len(a1);
    a2 = a1;
    a2[a1_len] = 42;
    if(a1_len <= ARRAY_SIZE)
        a2[a1_len+1] = TERMINATOR;

    a1 = malloc(sizeof(int) * ARRAY_SIZE);
    a1[0] = 41;
    a1[1] = TERMINATOR;
}

int main() 
{
    int a1[ARRAY_SIZE];
    int a2[ARRAY_SIZE];

    a1[0] = 10;
    a1[1] = 4;
    a1[2] = TERMINATOR;

    a2[0] = 7;
    a2[1] = 9;
    a2[2] = 11;
    a2[3] = TERMINATOR;

    jumbleArrays(a1, a2);

    printf("Contents of a1: ");
    for(int i = 0; i < ARRAY_SIZE && a1[i] != TERMINATOR; i++) {
        printf("%d ", a1[i]);
    }
    printf("\n");

    printf("Contents of a2: ");
    for(int i = 0; i < ARRAY_SIZE && a2[i] != TERMINATOR; i++) {
        printf("%d ", a2[i]);
    }
    printf("\n");

    return 0;
}

Почему при запуске программы выводится следующее:

Содержимое a1: 41

Содержимое a2: 10 4 42

Но вместо этого это Содержимое a1: 10 4 42

Содержимое a2: 7 9 11

JumbleArrays принимает указатель(ничего, кроме адреса), а затем вносит изменения в существующий массив a1.Затем он создает новый массив в куче, базовый адрес которого будет сохранен в a1, но похоже, что после того, как метод jumbleArrays () вернет, этот адрес больше не сохраняется в a1?В целом, я не уверен, почему a1 и a2 ссылаются на свои старые массивы, когда явно хранят разные адреса в jumbleArrays.

1 Ответ

1 голос
/ 09 апреля 2019
void jumbleArrays(int *a1, int *a2)
{
    int a1_len = array_len(a1);
    a2 = a1;

Обратите внимание, что a1 и a2 являются указателями и что после этой последней строки функция jumbleArrays больше не знает адрес массива a2 в main. Его переменная, хотя и называется a2, теперь содержит адрес массива a1. Таким образом, невозможно, чтобы эта функция после этой строки могла изменить исходный массив a2. Поэтому ваше ожидание того, что оно изменит содержание a2, не может быть оправдано. Он даже не знает, где находится a2 после этой строки.

Тогда имеем:

a1 = malloc(sizeof(int) * ARRAY_SIZE);

После этой точки локальный указатель a1 указывает на некоторую вновь выделенную память, и первоначальный указатель на исходный a1 теряется. Так что ничто после этой строки не может изменить исходный массив a1 - мы больше не знаем, где он находится. Так что ваше ожидание, что последующие строки изменят массив a1 в main, не оправдано.

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