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

能否访问并向void**写入数据?如何存储未知类型数据?

问题分析与解决方案

为什么会出现段错误?

你的代码存在两个核心问题:

  1. 类型不匹配:你把malloc返回的void*直接赋值给void** d。void**是「指向void指针的指针」,而你malloc的是一块用来存储int的内存,并非存储void*的数组,类型完全不兼容。
  2. 访问非法地址:malloc分配的内存未初始化,*d会读取这块内存前sizeof(void*)字节的随机值当作地址,你把这个随机地址强转为int*后解引用,必然会访问非法内存,触发段错误。

至于第一个例子中sizeof(*( (int *) *d ))能输出4,是因为sizeof是编译期计算的操作——编译器只需要知道*(int*)x的类型是int,直接返回int的大小,不会实际访问*d指向的内存,所以不会出错。

如何正确访问这块内存?

如果要存储int类型数据,直接用对应类型的指针接收malloc返回值即可:

int *d = malloc(sizeof(int) * 10);
*d = 1; // 直接给第一个int元素赋值,完全合法

如果确实需要用通用的void*存储,应该用void*而非void**:

void *d = malloc(sizeof(int) * 10);
*(int*)d = 1; // 将void*强转为int*后解引用赋值,正确

void**的适用场景是存储多个void指针的集合(比如不同类型对象的指针数组),不是用来存储普通数值类型的。

如何存储类型未知的数据?

通常有两种常用方案:

1. 标签联合(Tagged Union)

定义一个包含类型标记和联合的结构体,用标记区分当前存储的数据类型,联合用来容纳不同类型的数据:

// 定义类型标记枚举
typedef enum {
    TYPE_INT,
    TYPE_FLOAT,
    TYPE_STRING
} DataType;

// 通用数据结构体
typedef struct {
    DataType type;
    union {
        int i_val;
        float f_val;
        char* s_val;
    } data;
} GenericData;

// 使用示例
GenericData data_list[10];

// 存储int
data_list[0].type = TYPE_INT;
data_list[0].data.i_val = 42;

// 存储float
data_list[1].type = TYPE_FLOAT;
data_list[1].data.f_val = 3.14f;

// 读取时根据类型判断
if (data_list[0].type == TYPE_INT) {
    printf("Int value: %d\n", data_list[0].data.i_val);
}

2. void*数组+类型信息数组

如果需要存储不同类型的指针(而非值本身),可以用void*数组存储指针,同时用额外数组记录每个元素的类型:

void* ptr_arr[10];
DataType type_arr[10];

// 存储int变量的指针
int num = 100;
ptr_arr[0] = #
type_arr[0] = TYPE_INT;

// 存储字符串指针
char* str = "hello";
ptr_arr[1] = str;
type_arr[1] = TYPE_STRING;

// 读取示例
if (type_arr[0] == TYPE_INT) {
    printf("Int value: %d\n", *(int*)ptr_arr[0]);
}

注意:如果存储的是需要动态分配内存的数据(比如字符串),需要自行管理内存的分配与释放,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Ilya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 01:33:17