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

使用void*指针打包多类型数据后,能否正确解析访问其中内容?

问题分析与解决方案

核心问题:你的代码未实现连续内存打包

你当前的代码完全没有把数据写入到同一块连续内存中,pack只是被反复赋值为各个变量的独立地址,之后的指针偏移也没有实际存储数据。所以你设想的[char, char, size_t, size_t, size_t, char, char, char]连续内存布局根本不存在。

举个例子,这段循环:

for(int i = 0; i < size; i++, pack++, str++ ){
    pack = str;
}

每次循环pack都会被重新赋值为str的当前地址,pack++的偏移操作完全无效,没有任何数据被写入到内存中。后续对size、size2、zero的操作也是同理,只是让pack指向这些变量的栈地址,没有把它们的值拷贝到连续内存块里。

正确的打包实现(符合void*要求)

要实现你想要的连续内存布局,第一步需要分配一块足够大的连续内存,然后通过memcpy把数据依次写入:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    char *str = "hi";
    char *str2 = "bye";
    size_t size = 2;
    size_t size2 = 3;
    size_t zero = 0;

    // 计算总内存需求:2个char + 3个size_t + 3个char
    size_t total_size = sizeof(char)*2 + sizeof(size_t)*3 + sizeof(char)*3;
    // 分配连续内存,用void*接收
    void *pack = malloc(total_size);
    if (!pack) {
        perror("malloc failed");
        return 1;
    }

    void *current = pack; // 用current跟踪当前写入位置

    // 写入第一个字符串的2个char
    memcpy(current, str, sizeof(char)*2);
    current = (char*)current + sizeof(char)*2; // 按字节偏移,更规范

    // 写入三个size_t变量
    memcpy(current, &size, sizeof(size_t));
    current = (char*)current + sizeof(size_t);
    memcpy(current, &size2, sizeof(size_t));
    current = (char*)current + sizeof(size_t);
    memcpy(current, &zero, sizeof(size_t));
    current = (char*)current + sizeof(size_t);

    // 写入第二个字符串的3个char
    memcpy(current, str2, sizeof(char)*3);
    current = (char*)current + sizeof(char)*3;

    // 解包演示
    printf("=== 解包结果 ===\n");
    current = pack;

    // 读取前2个char
    char c1 = *(char*)current;
    current = (char*)current + sizeof(char);
    char c2 = *(char*)current;
    current = (char*)current + sizeof(char);
    printf("前两个字符:%c, %c\n", c1, c2);

    // 读取3个size_t
    size_t s1 = *(size_t*)current;
    current = (char*)current + sizeof(size_t);
    size_t s2 = *(size_t*)current;
    current = (char*)current + sizeof(size_t);
    size_t s0 = *(size_t*)current;
    current = (char*)current + sizeof(size_t);
    printf("三个size_t值:%zu, %zu, %zu\n", s1, s2, s0);

    // 读取后3个char
    char c3 = *(char*)current;
    current = (char*)current + sizeof(char);
    char c4 = *(char*)current;
    current = (char*)current + sizeof(char);
    char c5 = *(char*)current;
    current = (char*)current + sizeof(char);
    printf("后三个字符:%c, %c, %c\n", c3, c4, c5);

    free(pack); // 释放内存
    return 0;
}

void*遍历与访问的关键注意事项

  • void*不能直接解引用(比如*pack是非法的),必须先强制转换为对应类型的指针(如(char*)pack或(size_t*)pack)才能读取数据。
  • 指针偏移时,推荐先转换为char*再操作,因为char的大小固定为1字节,偏移逻辑更清晰,避免编译器对void*算术运算的差异处理。
  • 解包必须严格遵循打包的顺序和数据类型,否则会出现内存对齐错误或数据解析混乱。

为什么你之前的遍历找不到size_t变量

因为你从未把size、size2、zero的值写入到连续内存中,这些变量本身存储在栈上的分散位置,pack只是在指向它们的独立地址,并非连续内存块,所以遍历自然无法按预期找到这些值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 12:07:45