Указатель на указатель как параметр функции для геттера - PullRequest
0 голосов
/ 21 ноября 2018

Учитывая некоторую структуру:

struct Foo {
  // ...
};

Я хочу использовать функцию из библиотеки со следующей сигнатурой:

void getAllFoos(Foo** foos);

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

Как мне инициализировать foos, когда я хочу вызвать эту функцию?Будет ли достаточно «нулевого указателя» (Foo **), или я должен сначала получить количество foos и самостоятельно распределить достаточно памяти (как мне сделать это для указателя на указатель?)?А кто отвечает за освобождение памяти?

Ответы [ 3 ]

0 голосов
/ 21 ноября 2018

Вам нужно заранее знать, сколько Foo вы получите.Это невозможно обойти, если вы получите все Foo одновременно, и это встроено в интерфейс.Однако, если вы отвечаете за распределение памяти, вы можете использовать std::vector в качестве получателя и указать в качестве аргумента его член data():

std::vector<Foo> flexible_buffer(Foo_nb); // or reserve later
getAllFoos(&(flexible_buffer.data());
0 голосов
/ 21 ноября 2018

foos не нужно инициализировать , если можно предположить, что getAllFoos работает примерно так - он инициализирует foos для вас:

void getAllFoos(Foo** pfoos) {
    Foo* the_pointer_to_all_the_foos;
    // (1) maybe the_pointer_to_all_the_foos = malloc(10 * sizeof(Foo));
    // (2) maybe the_pointer_to_all_the_foos = new Foo[10];
    // (3) maybe the_pointer_to_all_the_foos is a static Foo[10]
    *pfoos = the_pointer_to_all_the_foos;
}

При использовании API выше getallFoos не имеет смысла читать значение pfoos.

Для его использования:

// in C, you should write: struct Foo* foos;
Foo* foos;
getAllFoos(&foos); // note: foos is Foo*, pfoos is Foo**

В общем, документация по API для getAllFoos должен задокументировать, что вам нужно сделать с foos в конце.В зависимости от того, что код делает [(1), (2), (3) сверху или что-то еще], вам может понадобиться free(foos), delete[] foos, ничего не делать или делать что-то еще.Мы не можем ответить на это информацией, приведенной в вопросе.

0 голосов
/ 21 ноября 2018

Вы должны вызвать эту функцию, передав ссылку указателя типа struct Foo.

struct Foo *foo = NULL;
getAllFoos(&foo);

Вы можете освободить foo, как показано ниже

free(foo); //Assuming getAllFoos allocated the memory and filled.


Будет ли достаточно "нулевого указателя" (Foo **)

Нет FOO * должен указывать на действительную память.

struct Foo **foo = NULL; getAllFoos(foo);

Если getAllFoos попытается разыменовать foo У вас будет неопределенное поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...