Подтвердить что ты не робот

C Двойной указатель на структуру

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

typedef struct
{
    int member;
} mystruct;

void myfunc(mystruct **data)
{
    (*data)->member = 1;
}

void main(int argc, char *argv[])
{
    mystruct **data;

    myfunc(data);

    printf("member = %d\n", (*data)->member);
}

Здесь был задан аналогичный вопрос: Как работать с указателем на указатель на структуру в C? о том, как изменить член структуры с помощью двойного указателя. Решением был синтаксис (*data)->member = 1;, который имеет смысл. Но в моем маленьком приложении здесь я получаю ошибку seg при выполнении этой строки. Что я делаю не так?

Спасибо

4b9b3361

Ответ 1

Вам нужно указать на что-то, если вы хотите разыменовать указатель. Попробуйте следующее:

void main(int argc, char *argv) {
    mystruct actualThing;
    mystruct *pointer = &actualThing;
    mystruct **data = &pointer;
    myfunc(data);

    printf("Member: %d", (*data)->member);
}

Ответ 2

Вы получили segfault, потому что вы не выделили структуру.

Значение data - это мусор, поэтому он указывает на какое-то место в памяти, которое не принадлежит вашему процессу или в противном случае недоступно.

Вам нужно сначала выделить объект типа mystruct. Вот вам рабочий пример: http://ideone.com/XIdJ8

Ответ 3

data не инициализируется и, следовательно, не указывает на какой-либо разумный адрес памяти. Более того, вокруг не существует структуры mystruct, поэтому на самом деле нет даже разумных данных. Для вашего примера вы хотите:

  • Создайте mystruct.
  • Сделайте указатель на него.
  • Сделайте указатель на этот указатель.

Ответ 4

Если вам нужно только передать двойной указатель на библиотечную функцию, вам не нужно создавать для нее переменную. Вы делаете обычную переменную указателя, инициализируете ее, чтобы указать на соответствующее хранилище (если это требуется функцией), затем передайте адрес указателя (таким образом создавая двойной указатель "на лету" ).

Я никогда не использовал libusb, поэтому я приведу пример, используя стандартную библиотечную функцию. С manpage:

   #include <stdlib.h>

   long int strtol(const char *nptr, char **endptr, int base);

Он выглядит только как двойной указатель. Это действительно одиночный указатель с симуляцией-переходом. Позволяет функции возвращать дополнительную информацию, кроме ее нормального возвращаемого значения. strtol возвращает длинное целое число, но также может сказать вам, в какой момент содержимое строки перестало выглядеть как число.

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

int main(void) {
    char *str = "99RED BALLOONS";
    char *what;
    long num;

    num = strtol(str, &what, 10);
    printf("Quantity: %ld;    Description: %s;\n", num, what);

    return 0;
}

Вывод:

Quantity: 99;    Description: RED BALLOONS;

Ответ 5

Вы передаете ему указатель, но указатель не указывает ни на что.

Это может быть более полезно:

void main(int argc, char *argv[])
{
    mystruct data;
    mystruct *ptr = &data;
    myfunc(&ptr);
    printf("member = %d\n", (*ptr)->member);
}