проблема массива и точки - PullRequest
0 голосов
/ 30 мая 2010

Здесь у меня плохая программа. Его выводы меня смущают, кто-нибудь может подсказать почему?

 #include <stdio.h>
 #include <stdlib.h>
 int main()
 {
    int i = 0;
    char *a_result[10];
    char *b_result[10];
    for (i = 0; i < 10; i++)
    {
        char a_array[10];
        char *b_array = malloc(10*sizeof(char));
        int j = 0;
        for (j = 0; j < 9; j++)
        {
            a_array[j] = 'a' + i;
            b_array[j] = 'a' + i;
        }
        a_array[j] = '\0';
        b_array[j] = '\0';
        a_result[i] = a_array;
        b_result[i] = b_array;

    }
    for (i = 0; i < 10; i++)
        printf("a_result: %s b_result: %s\n",a_result[i],b_result[i]);
    return 0;
} 

Я думаю, что a_result и b_result должны быть одинаковыми, но это не так.

Вот вывод на моем компьютере.

a_result: jjjjjjjjj b_result: aaaaaaaaa
a_result: jjjjjjjjj b_result: bbbbbbbbb
a_result: jjjjjjjjj b_result: ccccccccc
a_result: jjjjjjjjj b_result: ddddddddd
a_result: jjjjjjjjj b_result: eeeeeeeee
a_result: jjjjjjjjj b_result: fffffffff
a_result: jjjjjjjjj b_result: ggggggggg
a_result: jjjjjjjjj b_result: hhhhhhhhh
a_result: jjjjjjjjj b_result: iiiiiiiii
a_result: jjjjjjjjj b_result: jjjjjjjjj

Любое объяснение по этому поводу приветствуется!

Ответы [ 3 ]

3 голосов
/ 30 мая 2010
for (i = 0; i < 10; i++)
{
    char a_array[10];
    ...
    a_result[i] = a_array;
}

Вы объявляете массив в стеке в области действия for цикла. Это означает, что массив станет недействительным, как только вы выйдете из цикла for. То есть содержимое внутри a_result недопустимо.

Для переменных в стеке компилятор будет повторно использовать одну и ту же область памяти для a_array в каждом цикле (что не для b_array, поскольку свежая память будет получена из кучи malloc). Следовательно, для вашего случая a_result просто скопировал 10 одинаковых недействительных указателей.


Если вы хотите скопировать содержимое этого массива, сделайте тип a_result равным

char a_result[10][10];

и используйте

memcpy(a_result[i], a_array, sizeof(a_result[i]));

для копирования в результат.

0 голосов
/ 30 мая 2010

Массив

 char a_array[10];

выходит из области видимости в конце каждой итерации цикла и затем эффективно воссоздается в том же месте памяти. В итоге вы получите набор указателей, указывающих на последнее воссоздание, которое содержит строку "jjjjjj".

0 голосов
/ 30 мая 2010

Вы постоянно пишете над массивом (a_array) в одной и той же позиции, а затем сохраняете адрес в a_result[i] (a_result - это массив указателей). Таким образом, в конце каждый элемент a_result содержит идентичный адрес (a_array), а сам a_array имеет значения, записанные в последней итерации.

Хуже того, доступ к содержимому a_array (в том числе через указатели в a_result) вне цикла for является неопределенным поведением. Это хранилище можно использовать только в теле цикла.

Напротив, вы выделяете новую кучную память для b_array (которая на самом деле не является массивом) для каждой итерации и сохраняете этот (новый) указатель в b_result. Таким образом, вы не перезаписываете старые значения.

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