2015-12-19 3 views
0

Предположим, что у меня есть Структуры указателей, как, например:Попутный Структуры указателей

typedef struct person { 
    char* name; 
    struct person* neighbor; 
} person; 

typedef struct jail { 
    struct person* first_inmate; 
} jail; 

я пишу следующее выделить эти структур в куче так, что они сохраняются за пределами местной сферы:

void create_person(const char* person_name, person** person_ptr2ptr) { 
    if (!*person_ptr2ptr) 
     *person_ptr2ptr = (person*) malloc(sizeof(person)); 
    (*person_ptr2ptr)->name = (char*)person_name; 
    (*person_ptr2ptr)->neighbor = NULL; 
} 

jail* create_jail(void) { 
    jail* _jail; 
    _jail = (jail*) malloc(sizeof(jail)); 
    _jail->first_inmate = NULL; 
    return _jail; 
} 

Почему не могу я «вставить» эти person s в jail вот так?

void imprison(jail* jail_ptr, person* person_ptr) { 
    person* last_inmate = jail_ptr->first_inmate; 
    while (last_inmate != NULL) 
     last_inmate = last_inmate->neighbor; 
    last_inmate = person_ptr; 
} 

Я побегу в Segfault, когда я пытаюсь получить доступ к san_jose_jail->first_inmate или любой из имен заключенных:

int main(void) { 
    person* alice_ptr = NULL; 
    person* bob_ptr = NULL; 
    create_person("Alice", &alice_ptr); 
    create_person("Bob", &bob_ptr); 

    jail* san_jose_jail = create_jail(); 
    imprison(san_jose_jail, alice_ptr); 
    imprison(san_jose_jail, bob_ptr); 
    // Why don't the pointers match? 
    printf("Alice is at %p\n", (void*)alice_ptr); 
    printf("First prisoner is at %p\n", (void*)san_jose_jail->first_inmate); 
    // Segfaults after next line 
    printf("Last prisoner's name is %s\n", san_jose_jail->first_inmate->neighbor->name); 

    free(san_jose_jail); 
    free(alice_ptr); 
    free(bob_ptr); 
    return 0; 
} 

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

ответ

1

Проблема с этим утверждением:

last_inmate = person_ptr; 

Вы модифицирующих локальную копию neighbor указателя , а не тот, который находится внутри структуры, остается непривязанным. Метод imprison должен быть таким:

void imprison(jail* jail_ptr, person* person_ptr) { 
    person** last_inmate = &jail_ptr->first_inmate; 
    while (*last_inmate != NULL) 
     last_inmate = &(*last_inmate)->neighbor; 
    *last_inmate = person_ptr; 
} 
+0

Я получаю ошибку компиляции в строке: 'last_inmate = & last_inmate-> соседа;' я не думаю, что это типа-чеки: 'pointerfun.c: 30: 35: error: запрос для члена «соседа» в чем-то не структуре или объединении. «В противном случае это, кажется, правильный ответ и объяснение, я приму исправленную версию - спасибо! – Katie

+0

Я скорректировал его на '& ((* last_inmate) -> сосед);' - работает сейчас! Я думаю, что я понимаю концепцию примерно сейчас и могу вызывать остальное отсюда, огромное спасибо! – Katie

0

Чтобы добавить кого-то в тюрьму, Жюст добавить его в начале списка:

void imprison(jail* jail_ptr, person* person_ptr) { 
    person_ptr->neighbor = jail_ptr->first_inmate; 
    jail_ptr->first_inmate = person_ptr; 
} 
Смежные вопросы