птр *** не работает - PullRequest
       3

птр *** не работает

1 голос
/ 11 сентября 2011

Код не работает должным образом (segfault), когда он должен получить доступ к элементам foo через c.foos во втором цикле for в main.

Он только правильно отображает элемент fist, тогда при i =1 показывает мусор, и при i = 2 он, наконец, падает.

Так что я думаю, что это связано с математикой указателя.

Как это сделать правильно?Структуры данных не могут изменяться (нет, это не домашняя работа, это слишком упрощенный POC этой структуры данных).

#include <stdio.h>
#include <stdlib.h>

typedef struct _foo {
    int i;
} foo;

typedef struct _foo_container {
    foo ***foos;
} container;

foo** init_foos(void) {
    foo** f;
    int i;

    f = malloc(sizeof(foo*)*3);

    for(i=0; i < 3; i++) {
        f[i] = malloc(sizeof(foo));
        f[i]->i = i*11+1;
    }
    return f;
}

int main(void) {
    container c;
    foo **foos;

    foos = init_foos();

    c.foos = &foos;
    int i;
    for(i=0; i < 3; i++) {
        printf("%d %d\n", i, foos[i]->i);
    }
    for(i=0; i < 3; i++) {
        printf("%d %d\n", i, (**c.foos[i]).i);
    }
    //memory leaks, I know

    return EXIT_SUCCESS;
}

Примечание: этот код, похоже, работал.Я предполагаю, что что-то произошло со времени последнего обновления gcc, хотя я все еще могу делать что-то не так.

Добавление : извините всех за то, что пропустили *3, я написал этот POCторопиться.Фактический код выделяет количество необходимых указателей через php safe_emalloc().

Ответы [ 4 ]

2 голосов
/ 11 сентября 2011

В init_foo вы должны выделить 3 * sizeof(foo *).

2 голосов
/ 11 сентября 2011

Попробуйте:

printf("%d %d\n", i, (*(*c.foos)[i]).i);

Я думаю, что проблема в операторах приоритет .«[]» вычисляется перед «*», если вы не парентезируете выражение.

1 голос
/ 11 сентября 2011
f = malloc(sizeof(foo*));

Вы выделяете кусок памяти размером с указатель на foo.Но затем сразу же после этого вы индексируете его как f[i] с i до 2. Таким образом, вы получаете доступ к памяти, которую вы не распределили.

1 голос
/ 11 сентября 2011

Я думаю, что ваша проблема здесь:

f = malloc(sizeof(foo*));

Похоже, вам нужен массив указателей foo, но вы выделяете только один указатель foo.

Попробуйте изменить это на:

f = malloc(sizeof(foo*) * 3);
...