указатель на указатели в C - PullRequest
1 голос
/ 19 марта 2011

Мне нужна помощь с указателями в C. У меня есть две структуры, структура которых выглядит следующим образом:

    typedef struct s{
        s2** d;
        struct s* next;
    }s;


 typedef struct s2{
        c* fi;
        struct s2* next;
    }s2;

И у меня есть такая функция:

void modify(c* a, s2* b){   //c* is a pointer to a struct
    s* rd = malloc(sizeof(s);
    rd->next = NULL;
    //need also to initialize the field "d" of the "s" struct
}

Thisгенерирует ошибку.Мне нужно, чтобы структура rd указывала на b, как в примере.Мне нужно хранить двойной указатель, потому что s2 связаны в виде списка, поэтому мне нужен указатель **, чтобы иметь возможность удалить первый элемент списка.Я делал назначение в комментарии, например, rd-> d = & b, но когда я пытаюсь использовать поле «d» в функции, у меня читается недопустимая память, и я не могу понять, почему.

1 Ответ

1 голос
/ 19 марта 2011

Полагаю, проблема в следующем:

Вы передаете s2* b в качестве аргумента modify, поэтому этот указатель находится в стеке.Теперь, когда вы назначаете rd->d = &b, вы берете это место в стеке, которое будет действовать только до тех пор, пока выполнение не выйдет из области действия modify.Таким образом, когда вы разыменовываете rd->d позже, вы получаете доступ к этому (теперь недопустимому) расположению в стеке, что приводит к мусору или аварийному завершению.(Однако в этом сценарии вы должны иметь возможность правильно разыменовывать rd->d, находясь в modify.)

Вероятно, вы захотите изменить способ передачи b в модификацию, скорее всего вчто-то вроде s2** b, так что вы можете правильно передать указатель на s2 в другой структуре вместо того, чтобы указывать на s2, находящийся в стеке для modify.

В основном так:

void modify(c* a, s2** b) {
    s* rd = malloc(sizeof(s));
    rd->next = NULL;
    rd->d = b;
}

и назовите его как

s2* myS2 = ...;
modify(<whatever>, &myS2->next);

Это должно позволить вам передать местоположение указателя на экземпляр s2, который вы можете сохранить иразыменование даже после завершения modify (хотя и не проверено).

...