присвоение составного литерала указателю массива дает ожидаемый результат и мусор в одном и том же месте и времени? - PullRequest
0 голосов
/ 14 декабря 2011
#include <stdio.h>

int main(void) {
    int a[5], *p, i;
    p = a;
    p = (int []){1, 2, 3, 4, 5};
    for (i = 0; i < 5; i++, p++) {
        printf("%d == %d\n", *p, a[i]);
    }
    return 0;
}

Глядь (YMMV):

$ gcc -O -Wall -Wextra -pedantic -std=c99 -o test test.c; ./test
1 == -1344503075
2 == 32767
3 == 4195733
4 == 0
5 == 15774429

Печать массива с помощью арифметики указателя показывает, что он действительно содержит целочисленную последовательность от 1 до 5, но при печати снова того, что, как предполагается, тот же массив, выраженный через Indeces, дает неинициализированное дерьмо. Почему?

Ответы [ 5 ]

4 голосов
/ 14 декабря 2011

Вы присваиваете только p, но не a, поэтому a никогда не инициализируется.

int a[5], *p, i;
// a uninitialized, p uninitialized
p = a;
// a uninitialized, p points to a
p = (int []){1, 2, 3, 4, 5};
// a uninitialized, p points to {1, 2, 3, 4, 5}
2 голосов
/ 14 декабря 2011

Вы никогда не инициализируете элементы a.Оба назначения на p меняются, где p баллов;ни присвоение ничего не делает для a или его элементов.

1 голос
/ 14 декабря 2011

Вы присваиваете значение a для p, а затем немедленно заменяет его значением другого массива целых.В printf("%d == %d\n", *p, a[i]) *p и a[i] больше не ссылаются на одно и то же место в памяти, а a остается неинициализированным (следовательно, мусором).

0 голосов
/ 14 декабря 2011

Ваш код эквивалентен этому:

int a[5];
int b[5] = { 1, 2, 3, 4, 5 };

for (i = 0; i < 5; i++)
    printf("%d == %d\n", b[i], a[i]);

Так как a неинициализирован, вы получаете непредсказуемые значения (фактически даже неопределенное поведение даже читать эти переменные).

0 голосов
/ 14 декабря 2011

Вы присваиваете указатель массива, вы не копируете данные в массив.Таким образом, вы получаете данные из одного источника и мусор из другого.

...