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

将字节数组转换为含指针的结构体时原数组被修改的问题排查

问题描述

我想要将一个字节数组转换为包含两个指针的结构体,但每次设置指针时,原字节数组都会被修改。通常我会使用末尾的柔性数组(如char name[])来处理这类情况,但由于该结构体中存在两个动态大小的字段,无法采用这种方式。

我也尝试过内存分配(见注释代码),但因为字节数组已包含所需的全部数据,我认为无需进行动态分配。请问我忽略了什么问题?

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

typedef struct {
    uint8_t mac[6];
} __attribute__ ((packed)) mac_t;

typedef struct {
    char type;
    uint16_t interval;
    uint16_t window;
    uint8_t name_length;
    uint8_t macs_length;
    char* name;
    mac_t* macs;
} __attribute__ ((packed)) set_config_t;


int main() {
    const uint8_t byte[] = {0x01, 0x02, 0x00, 0x03, 0x00, 0x05, 0x01, 'T', 'e', 's', 't', '\0', 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
    
    printf("byte array before casting: ");
    for(int i = 0; i < sizeof(byte); i++) {
        printf("0x%02x ", byte[i]);
    }
    printf("\n");
    
    set_config_t* data = (set_config_t*) byte;

    data->name = &byte[7];
    data->macs = &byte[12];
    
    //data->name = malloc(sizeof(data->name_length));
    //data->macs = malloc(sizeof(data->macs_length) * sizeof(mac_t));
    //memcpy(data->name, &byte[7], data->name_length);
    //memcpy(data->macs, &byte[12], data->macs_length * sizeof(mac_t));
    
    printf("byte array after casting: ");
    for(int i = 0; i < sizeof(byte); i++) {
        printf("0x%02x ", byte[i]);
    }
    printf("\n\n");
    
    printf("Sizeof byte %d\n", sizeof(byte));
    printf("Sizeof set_scan_config_t %d\n", sizeof(set_config_t));
    
    printf("type: %d\n", data->type);
    printf("interval: %d\n", data->interval);
    printf("window: %d\n", data->window);
    printf("name_length: %d\n", data->name_length);
    printf("macs_length: %d\n", data->macs_length);
    printf("name: %s", data->name);

    return 0;
}

程序运行输出:

byte array before casting: 0x01 0x02 0x00 0x03 0x00 0x05 0x01 0x54 0x65 0x73 0x74 0x00 0xaa 0xbb 0xcc 0xdd 0xee 0xff 
byte array after casting:  0x01 0x02 0x00 0x03 0x00 0x05 0x01 0x47 0x20 0x61 0x95 0xfd 0x7f 0x00 0x00 0x4c 0x20 0x61

Sizeof byte 18
Sizeof set_scan_config_t 23
type: 1
interval: 2
window: 3
name_length: 5
macs_length: 1
name: G a��

问题根源

  • 你错误地将只读字节数组byte直接强制转换为set_config_t*指针,并修改结构体的指针成员。
  • set_config_t结构体在64位系统下总大小为23字节(前5个固定字段占7字节,两个指针成员各占8字节),但原字节数组仅18字节。结构体的name和macs指针成员会占用原字节数组从第7位开始的内存:
    • name指针占用偏移7-14的8字节
    • macs指针占用偏移15-22的8字节
  • 当你给data->name和data->macs赋值时,本质是把指针的地址值直接写入原字节数组的内存区域,直接覆盖了数组中存储的原始数据(比如'T'、'e'等字符),这就是数组内容被修改的核心原因。

解决方案

不需要动态分配内存,只需创建独立的set_config_t结构体实例,将原字节数组中的固定字段解析到结构体中,再让结构体的指针成员直接指向字节数组中对应的数据区域即可,完全不会修改原数组内容。

修正后的代码

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

typedef struct {
    uint8_t mac[6];
} __attribute__ ((packed)) mac_t;

typedef struct {
    char type;
    uint16_t interval;
    uint16_t window;
    uint8_t name_length;
    uint8_t macs_length;
    char* name;
    mac_t* macs;
} __attribute__ ((packed)) set_config_t;


int main() {
    const uint8_t byte[] = {0x01, 0x02, 0x00, 0x03, 0x00, 0x05, 0x01, 'T', 'e', 's', 't', '\0', 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
    
    printf("byte array: ");
    for(int i = 0; i < sizeof(byte); i++) {
        printf("0x%02x ", byte[i]);
    }
    printf("\n");
    
    // 创建独立的结构体实例,而非直接转换原数组
    set_config_t data;
    
    // 从字节数组中解析固定长度字段
    data.type = byte[0];
    // 若字节序与系统不一致,需自行转换,此处假设匹配
    memcpy(&data.interval, &byte[1], sizeof(data.interval));
    memcpy(&data.window, &byte[3], sizeof(data.window));
    data.name_length = byte[5];
    data.macs_length = byte[6];
    
    // 让指针直接指向原数组中的对应数据区域
    data.name = (char*)&byte[7];
    data.macs = (mac_t*)&byte[12];
    
    printf("\nSizeof byte %d\n", sizeof(byte));
    printf("Sizeof set_config_t %d\n", sizeof(set_config_t));
    
    printf("\ntype: %d\n", data.type);
    printf("interval: %d\n", data.interval);
    printf("window: %d\n", data.window);
    printf("name_length: %d\n", data.name_length);
    printf("macs_length: %d\n", data.macs_length);
    printf("name: %s\n", data.name);
    
    // 验证原数组未被修改
    printf("\nbyte array after operation: ");
    for(int i = 0; i < sizeof(byte); i++) {
        printf("0x%02x ", byte[i]);
    }
    printf("\n");

    return 0;
}

运行输出

byte array: 0x01 0x02 0x00 0x03 0x00 0x05 0x01 0x54 0x65 0x73 0x74 0x00 0xaa 0xbb 0xcc 0xdd 0xee 0xff 

Sizeof byte 18
Sizeof set_config_t 23

type: 1
interval: 2
window: 3
name_length: 5
macs_length: 1
name: Test

byte array after operation: 0x01 0x02 0x00 0x03 0x00 0x05 0x01 0x54 0x65 0x73 0x74 0x00 0xaa 0xbb 0xcc 0xdd 0xee 0xff 

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 03:15:05