如何正确对void指针进行解引用?附C++代码示例分析
如何正确解引用void指针?
首先,我们先拆解你给出的代码,分析里面的void指针操作哪些是对的,哪些有问题,再总结正确的操作方法。
先看你的代码:
void func(const char* str) { void *s = &str; std::cout << *(char**)s << std::endl; } int main() { char *str = "hello world"; func(str); char *str_1 = "Hello world"; void *ptr_1 = str; std::cout << (char*)ptr_1 << std::endl; // std::cout << *(char**)ptr_1 << std::endl; return 0; }
代码里的操作分析
1. func函数中的操作(正确,但可以更严谨)
void *s = &str;:这里s存储的是函数参数str的地址——str本身是一个const char*指针,所以s实际是指向指针的指针(类型等价于const char**)。*(char**)s:把s强制转换为char**(严格来说应该用const char**,避免const属性丢失),解引用后得到的就是原来的const char*指针,std::cout对char*类型有重载,会输出它指向的字符串,所以这行代码能正常输出hello world,逻辑是对的。
2. main中注释掉的行(错误,会导致未定义行为)
void *ptr_1 = str;:这里ptr_1直接指向字符串"Hello world"的首地址,本质是一个一级char*指针,不是指向指针的指针。- 如果强行执行
*(char**)ptr_1,相当于把字符串的前4/8个字节(取决于平台的指针长度)当成一个char*的地址去访问,这显然是错误的——要么程序崩溃,要么输出乱码,属于C++标准里的未定义行为,所以注释掉是正确的选择。 - 而
std::cout << (char*)ptr_1 << std::endl;是正确的:把void*转成char*后,cout会输出对应的字符串,这是符合预期的用法。
正确解引用void指针的核心规则
void指针本身没有类型信息,编译器不知道它指向的数据是什么类型,所以绝对不能直接解引用void指针,必须先完成两个步骤:
明确void指针实际指向的数据类型
你得清楚这个void指针到底存的是什么地址:是单个int?是char*字符串?还是指向指针的指针?强制转换为匹配的指针类型后再操作
- 如果指向单个
int:void* p = # int val = *(int*)p; - 如果指向
char*字符串:void* p = str; std::cout << (char*)p;(这里不需要解引用,因为cout对char*直接输出字符串) - 如果指向指针(比如
char**):void* p = &str; char* inner_str = *(char**)p;
- 如果指向单个
额外注意事项
- 类型转换必须严格匹配,否则会触发未定义行为(比如把指向
int的void指针转成char*去解引用,会读取错误的字节)。 - 在C++中,尽量优先使用模板代替void指针,模板能保留类型信息,更安全也更易维护。
- 如果必须使用void指针,一定要做好注释,明确它实际指向的类型,避免后续代码出错。
内容的提问来源于stack exchange,提问作者bohdan_syrovetnyk
相关产品推荐
相关产品推荐

