Segfault при разыменовании указателя на указатель в структуре - PullRequest
0 голосов
/ 09 июня 2018

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

Создайте человека в person_init и дайте ему имя (Джон).Имя - это указатель на строку символов.Я не могу printf() без проблем в этой функции.Возвращаясь к функции main(), я снова могу printf() назвать без проблем.Но затем, когда я вхожу в новую функцию и пытаюсь printf(), я получаю ошибку сегмента.Я действительно смущен, потому что я почти уверен, что в куче выделяется name.

Что мне здесь не хватает?

код:

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

/* structure with a pointer to pointer member */
struct person {
    char **name;
};


/* allocate space for the strucutre */
int person_init(struct person **p)
{
    struct person *newp = malloc(sizeof(struct person));

    /* give a name, allocated on the heap */
    char *name = malloc(sizeof(char) * 5);
    *name = 'J';
    *(name + 1) = 'o';
    *(name + 2) = 'h';
    *(name + 3) = 'n';
    *(name + 4) = '\0';
    newp->name = &name;
    *p = newp;

    printf("Name in init: %s\n", *(*p)->name); /* this works */

    return 0;
}


void print_name(struct person *p)
{
    printf(*p->name);
}


int main()
{
    struct person *person;
    person_init(&person);
    printf("Name in main: %s\n", *person->name);   /* works */
    print_name(person);                            /* segfault */
}

1 Ответ

0 голосов
/ 09 июня 2018

Вот проблема:

newp->name = &name;

newp->name теперь указывает на name, который является локальной переменной в person_init.Как только person_init возвращается, name исчезает, а newp->name является недопустимым указателем.Любая попытка использовать его впоследствии приводит к неопределенному поведению.

Исправление:

struct person {
    char *name;
};

И инициализация его как

newp->name = name;

Теперь newp->name является копией name, т.е. он указывает на выделенную строку.

...