C Pointers - Структуры, которые являются массивами - PullRequest
0 голосов
/ 02 сентября 2018

Я работаю над этим кодом уже несколько часов и не могу понять, почему printf только печатает мусор, я новичок в переполнении стека и довольно плохо знаком с C, поэтому, пожалуйста, простите меня за любые ошибки в этом посте. Я искал указатели на структуры, которые являются массивами, и не смог найти ничего полезного.

typedef struct my
{
    int x;
    int y;
} My;

My * main2(void);

void show(void)
{
    My * m = main2();

    printf("%u\n", m);

    printf("%u\n", m);
    printf("%d\n", m->x);
    printf("%d\n", m->y);
    m++;
    printf("%u\n", m);
    printf("%d\n", m->x);
    printf("%d\n", m->y);
    m++;
    printf("%u\n", m);
    printf("%d\n", m->x);
    printf("%d\n", m->y);
}

My * main2(void)
{
    My j[3];
    j[0].x = 2;
    j[0].y = 4;

    j[1].x = 3;
    j[1].y = 5;

    j[2].x = 7;
    j[2].y = 9;

    printf("%u\n", j);
    return j;
}

int main()
{
    show();

    return 0;
}

Ответы [ 3 ]

0 голосов
/ 02 сентября 2018

почему printf только печатает мусор? Это из-за того, что вы возвращаете адрес локальной переменной здесь

My j[3];
...
...
return j; /* j is a local array, its scope is within this this function not outside */

ваш компилятор мог бы предупредить вас вот так

функция возвращает адрес локальной переменной [-Werror = return-local-addr]

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

Также при печати m указатель структуры, используйте %p вместо спецификатора формата %u. например,

printf("%p\n", (void*)m);
0 голосов
/ 02 сентября 2018

Хорошо, я получил ответ, я забыл об этом действительно очень важном, все в функции "ушло" после того, как функция вернулась, спасибо обоим людям, которые помогли ответить на это:)

typedef struct my
{
    int x;
    int y;
} My;

void getData(My * pos)
{
    printf("%d", pos->x);
    printf("%d", pos->y);
    pos++;
    printf("%d", pos->x);
    printf("%d", pos->y);
}

int main()
{
    My x[2];

    x[0].x = 3;
    x[0].y = 4;

    x[1].x = 5;
    x[1].y = 6;

    getData(x);

    return 0;
}
0 голосов
/ 02 сентября 2018

Переменные, определенные внутри функции, имеют только время жизни этой функции. Как только функция возвращается, переменные по существу перестают существовать.

Теперь, если вы вернете указатель на такую ​​переменную (или на первый элемент массива, как вы), и эти данные больше не будут существовать, тогда вы получите неопределенное поведение когда вы пытаетесь использовать указатель.

Один из способов решения такой проблемы - передать массив (или, опять же, указатель на его первый элемент) в качестве аргумента функции:

void main2(My *j)
{
    j[0].x = 2;
    // And so on...
}

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

Это означает, что вы можете передать его, как и любую другую переменную:

My arr[3];
main2(arr);  // equal to main2(&arr[0]);

В другом примечании формат для печати указателя с использованием printf равен "%p". Указатель также должен быть приведен void *:

printf("%p\n", (void *) j);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...