Как объявление указателя «void *» и ключевое слово «void» связаны во время выделения памяти? - PullRequest
1 голос
/ 19 марта 2019

Так как указатель C возвращает «void *», и в дополнение к своему собственному адресу он может как-то ссылаться на объем памяти, зарезервированный malloc (size), я спрашиваю себя, действительно ли объявление «void *» является чем-то полностьюне относится к типу «void», используемому для выполнения процедур, и если «void *» на самом деле является типом, который сам содержит информацию, такую ​​как размер выделенного блока памяти, с «внутренней» структурой, аналогичной показанной ниже.

//An imaginary internal implementation of "type" void* used to create pointers

struct void*
{
    char[4] address; //for 32bit systems;
    int size; //memory block size;
};

void* ptr=malloc(10); //create a pointer called ptr of 10 bytes

Ответы [ 4 ]

5 голосов
/ 19 марта 2019

Использование ключевого слова void может действительно иметь различную семантику в зависимости от контекста:

  • Это может означать ничего , например, void myfunction(...) { ... } или int my_other_function(void) {...}
  • Это может означать что угодно , например, void *p = ...;

В C пустой указатель - это указатель, который может указывать на что угодно. В C ++ также следует избегать использования, насколько это возможно, и std::any следует отдавать предпочтение.

Важное замечание о вашей воображаемой реализации: указатель void сам по себе ничего не знает о размере объекта, на который он указывает.

2 голосов
/ 19 марта 2019

void имеет более одного использования;это все.void и void* очень разные звери.Обратите внимание, что void* - это , а не - ключевое слово, но void - это.

Не думайте, что void* - это ваша структура.Это просто указатель, который был преобразован из другого типа путем приведения.malloc возвращает void*, который может быть преобразован в другой тип указателя с помощью механизма, который несколько парадоксально делает невозможным запись malloc на переносимом языке C.

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

void* ptr=malloc(10); создает 10 байт необработанных неинициализированных данных в куче. Эти данные на данный момент не имеют типа.

Он не"создает указатель с именем ptr из 10 байтов". Переменная ptr имеет размер sizeof(void*) байт и выделяется как «автоматическое хранение» (вероятно, в стеке), независимо от того, куда вы ее указали.

См. Программа использует разные области памяти для статических объектов, автоматических объектов и динамически размещаемых объектов для объяснения того, где разные переменные, вероятно, размещены на основных компьютерах.

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

Нет, они не совсем не связаны.void - это тип, который ( C11 6.2.5p19 )

содержит пустой набор значений;это неполный тип объекта, который не может быть завершен.

И void * - это тип указателя, который указывает на объект указанного типа.

Любой тип указателя объекта может бытьпреобразован в другой тип указателя объекта с явным приведением , учитывая, что указатель соответствующим образом выровнен;единственное преобразование между типами указателей, которое может произойти без приведения в C, - это преобразования в void * и обратно;следовательно, статус void * как тип общего указателя.

Тип void сам по себе может использоваться для других задач - например, выражение может быть приведено к void, чтобы сигнализировать, что значение находится в процессенамеренно игнорируется или используется как тип возвращаемого значения, чтобы сигнализировать, что функция не возвращает значение.Единственная семантическая перегрузка - использование void в прототипе: int func(void), чтобы сигнализировать, что функция не принимает никаких аргументов.

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