void *
是一个通用指针,但是void **
呢? void **
也是通用指针吗?
我们可以将void **
强制转换为int **
,char **
等等。
我会感谢堆栈溢出系列的任何信息。
答案 0 :(得分:19)
没有。 void**
是指向void*
的指针,没有别的。只有void*
的行为类似于通用指针。
请注意,实际尝试它可能会产生一致的结果,但只有标准规定了上述内容,其他任何内容都是未定义的行为,可能会毫不留情地崩溃。
答案 1 :(得分:5)
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
指针的指针是与指针截然不同的野兽。指针上相对安全的类型更改在指针指针上不安全。
答案 2 :(得分:4)
Void **一个通用指针?
void **
不是通用指针。标准说只有void *
是一个通用指针。
关于指针和内存分配指针的一个观点:虽然
void *
返回的malloc
类型是泛型指针,适合分配到或来自任何类型的指针,假设类型void **
都不是指向指针的泛型指针。
我们可以将
void **
强制转换为int **
,char **
等等。
没有。你不应该。
C-FAQ说:
C 中没有通用的指向指针类型。
void *
仅作为通用指针使用,因为当其他指针类型分配到void *
时,会自动应用转换(如果需要);如果尝试在指向void **
以外的指针类型的void *
值上进行间接尝试,则无法执行这些转换。当您使用void **
指针值时(例如,当您使用*
运算符访问void *
指向的void **
值时),编译器无法知道该void *
值是否曾从其他指针类型转换为。它必须假设它只不过是void *
;它无法执行任何隐式转换。换句话说,您使用的任何
void **
值必须是某个地方实际void *
值的地址;像(void **)&dp
这样的演员,虽然他们可能会关闭编译器,但是不可移植(甚至可能不会做你想要的事情;另见问题13.9)。 如果void **
指向的指针不是void *
,并且它的大小或表示形式与void *
不同,则编译器不会是能够正确访问。
答案 3 :(得分:0)
C 实现可以自由扩展语言,允许 void**
在存在合适的强制转换运算符的情况下用作指向任何类型的通用指针,并且在标准之前的日子里实际上可以这样做的实现经常这样做。该标准并未强制要求进行此类处理,因为有些平台无法有效地适应此类使用。据推测,作者认为,要求需要让他们的代码在这些平台上工作的程序员跳过箍来解决缺少“指向任何数据指针的指针”类型的问题比要求的危害要小实现跳过箍以适应这样的构造,而不考虑他们的客户是否会使用它们。这样的判断并不意味着标准的作者打算要求程序员跳过这样的圈套,即使在编写永远不会被要求在此类平台上运行的代码时也是如此。可以通过 -fno-strict-aliasing
选项将 Clang 和 gcc 配置为支持此类构造。