Void ** универсальный указатель?

c++ c

4403 просмотра

3 ответа

void *это общий указатель, но как насчет void **? Это void **также общий указатель?

Можем ли мы типаж void **к int **, char **и так далее.

Я был бы благодарен, чтобы собрать семейство переполнения для любой информации по этому вопросу.

Автор: Adarsh Источник Размещён: 12.11.2019 09:53

Ответы (3)


19 плюса

Решение

void**это указатель void*, и ничего больше. void*Действует только как общий указатель.

Обратите внимание, что на самом деле попытка его выполнения, вероятно, даст согласованные результаты, но стандарт требует только вышеперечисленного, все остальное является неопределенным поведением и может привести к краху без жалости.

Автор: Quentin Размещён: 21.08.2014 01:29

6 плюса

void**является указателем void*. Помимо неопределенного поведения (которое, хотя и страшно, поведение часто определяется вашим компилятором), это также огромная проблема, если вы выполните reinterpret_cast:

int x = 3;
char c = 2;
int* y = &x;
void* c_v = &c; // perfectly safe and well defined
void** z = reinterpret_cast<void**>(&y); // danger danger will robinson

*z = c_v; // note, no cast on this line
*y = 2; // undefined behavior, probably trashes the stack

Указатели на указатели очень разные звери, чем указатели. Изменения типов, которые относительно безопасны для указателей, не безопасны для указателей на указатели.

Автор: Yakk - Adam Nevraumont Размещён: 21.08.2014 01:37

4 плюса

Void ** универсальный указатель?

void **не является общим указателем. Стандарт говорит только о том, void *чтобы быть общим указателем.

Глава 22: Указатели на указатели :

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


Можем ли мы типаж void **к int **, char **и так далее.

Нет, ты не должен.

C-FAQ говорит, что:

В Си нет общего типа указатель-указатель . void *действует как универсальный указатель только потому, что преобразования (при необходимости) применяются автоматически, когда другие типы указателей назначаются и из них void *; эти преобразования не могут быть выполнены, если предпринята попытка косвенного обращения к void **значению, которое указывает на тип указателя, отличный от void *. Когда вы используете void **значение указателя (например, когда вы используете *оператор для доступа к void *значению, на которое void **указывает точка), компилятор не может узнать, было ли это void *значение однажды преобразовано из какого-либо другого типа указателя . Надо полагать, что это не что иное, как а void *; он не может выполнять какие-либо неявные преобразования.

Другими словами, любое void **значение, с которым вы играете, должно быть адресом фактического void *значения где-то; Такие приведения, как (void **)&dp, хотя они могут закрывать компилятор, являются непереносимыми (и могут даже не выполнять то, что вы хотите; см. также вопрос 13.9). Если указатель, на который void **указывает указатель, не является a void *, и если он имеет другой размер или представление, отличное от a void *, то компилятор не сможет получить к нему правильный доступ .

Автор: haccks Размещён: 21.08.2014 02:06
Вопросы из категории :
32x32