void * является общим указателем, но как насчет void **? Является ли void ** общим указателем?
Можем ли мы отображать void ** на int **, char ** и так далее.
Я был бы благодарен за переполнение семейства стека за любую информацию об этом.
void * является общим указателем, но как насчет void **? Является ли void ** общим указателем?
Можем ли мы отображать void ** на int **, char ** и так далее.
Я был бы благодарен за переполнение семейства стека за любую информацию об этом.
Нет. void** является указателем на void*, и больше ничего. Только void* действует как общий указатель.
Обратите внимание, что на самом деле попытка его, вероятно, даст согласованные результаты, но только вышеизложенное предусмотрено стандартом, все остальное - Undefined Behavior и может сработать без пощады.
void** является указателем на void*. Помимо того, что это поведение undefined (которое в то время как страшно, поведение часто определяется вашим компилятором), это также огромная проблема, если вы выполняете 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
Указатели на указатели - очень разные звери, чем указатели. Изменения типа, которые относительно безопасны для указателей, небезопасны для указателей на указатели.
Void ** общий указатель?
void ** не является общим указателем. Стандарт говорит только о void * как общий указатель.
Одна боковая точка для указателей на указатели и распределение памяти: хотя тип
void *, возвращаемыйmalloc, является общим указателем, подходящим для назначения или указателям любого типа, гипотетический типvoid **не является общим указателем на указатель.
Можем ли мы привести
void **кint **,char **и так далее.
Нет. Тебе не следует.
C-FAQ говорит, что:
В C нет общего типа указателя на указатель.
void *действует как общий указатель только потому, что преобразования (если необходимо) применяются автоматически, когда другим типам указателей присваиваются иvoid *'s; эти преобразования не могут быть выполнены, если попытка сделана косвенной по значениюvoid **, которая указывает на тип указателя, отличный отvoid *. Когда вы используете значение указателяvoid **(например, когда вы используете оператор*для доступа к значениюvoid *, которому указывают точкиvoid **), компилятор не знает, что значениеvoid *было однажды преобразовано из некоторого другого типа указателя. Он должен предположить, что это не более чем avoid *; он не может выполнять никаких неявных преобразований.Другими словами, любое значение
void **, с которым вы играете, должно быть адресом фактического значенияvoid *где-то; отличные от(void **)&dp, хотя они могут закрыть компилятор, являются нелегальными (и могут даже не делать то, что вы хотите, см. также вопрос 13.9). Если указатель, на который указываетvoid **, не являетсяvoid *, и если он имеет другой размер или представление, чемvoid *, тогда компилятор не сможет получить к нему доступ правильно.