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

Психическая модель для void * и void **?

Примечание. Я опытный программист на С++, поэтому мне не нужны никакие основы указателя. Это просто, что я никогда не работал с void** и с трудом получаю мою ментальную модель, скорректированную на void* vs. void**. Я надеюсь, что кто-то сможет объяснить это в хорошем смысле, чтобы легче запомнить семантику.

Рассмотрим следующий код: (компилируется, например, VС++ 2005)

int main() {
  int obj = 42;
  void* ptr_to_obj = &obj;
  void* addr_of_ptr_to_obj = &ptr_to_obj;
  void** ptr_to_ptr_to_obj = &ptr_to_obj;
  void* another_addr = ptr_to_ptr_to_obj[0];
  // another_addr+1; // not allowed : 'void*' unknown size
  ptr_to_ptr_to_obj+1; // allowed
}
4b9b3361

Ответ 1

void* - это указатель на что-то, но вы не знаете, что. Поскольку вы не знаете, что это такое, вы не знаете, сколько места оно занимает, поэтому вы не можете увеличивать указатель.

void** является указателем на void*, поэтому он является указателем на указатель. Мы знаем, как много указателей на комнату занимают, поэтому мы можем увеличивать указатель void**, указывая на следующий указатель.

Ответ 2

A void* указывает на объект, тип которого неизвестен компилятору.

A void** указывает на переменную, которая хранит такой void*.

Ответ 3

A void * может указывать на что угодно (кроме функций). Таким образом, он может даже указывать на указатели, поэтому он может даже указывать на другие объекты void *.

A void ** - это указатель на void *, поэтому его можно использовать только для объектов void *.

Ответ 4

void вводит в заблуждение, потому что это звучит как null. Однако лучше думать о void как о неуказанном типе. Таким образом, void* является указателем на неуказанный тип, а void** является указателем на указатель для неуказанного типа.

Ответ 5

void - это тип, который не имеет объектов.

void * является обычным скалярным типом.

void ** также является обычным скалярным типом, который указывает на void *.


void * может использоваться для указания на что угодно, но я предпочитаю использовать его только для неинициализированного хранилища. Обычно существует лучшая альтернатива указанию a void * на фактическом объекте.