You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确对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指针,必须先完成两个步骤:

  1. 明确void指针实际指向的数据类型
    你得清楚这个void指针到底存的是什么地址:是单个int?是char*字符串?还是指向指针的指针?

  2. 强制转换为匹配的指针类型后再操作

    • 如果指向单个int:void* p = &num; 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:45:38