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

结构体初始化异常:seldata前三个成员值错误的技术问询

问题根源与修复方案

核心错误分析

你的代码存在三处内存相关问题,其中**data指针的内存分配大小不足**是导致seldata前三个元素异常的直接原因:

  1. data内存分配大小错误

    screen->data=(char**)malloc((screen->datsize));
    

    data是char**类型,需要存储7个char*指针,每个指针在64位系统占8字节,总共需要7*8=56字节,但你只分配了7字节。后续执行memcpy(screen->data,HOME_SCREEN,sizeof(HOME_SCREEN))时,会向这7字节空间写入56字节数据,直接触发堆内存越界,溢出内容会覆盖紧接在data内存块后的seldata指针数组。

  2. seldata内存分配的类型不匹配

    screen->seldata=(uint8_t**)malloc(screen->selsize*sizeof(uint8_t**));
    

    seldata是uint8_t**类型,每个元素是uint8_t*指针,应该用sizeof(uint8_t*)计算分配大小。虽然64位系统中uint8_t*和uint8_t**大小相同,但这是不规范写法,易在其他环境出错。

  3. memcpy字节数写法不严谨

    memcpy(screen->seldata[i],HOME_SEL[i],3);
    

    虽然uint8_t占1字节,3字节是正确的,但写成3*sizeof(uint8_t)更规范,能避免后续类型调整时出错。

现象解释

  • 函数内打印seldata[0][0]正确:因为你在memcpy(data)之前就完成了seldata的初始化并打印,此时seldata的指针数组还未被越界的memcpy破坏。
  • main中seldata[0][0]输出52:越界的memcpy把HOME_SCREEN里的字符串指针覆盖到了seldata的前几个位置,seldata[0]变成了字符串"4.DISP"的地址,访问[0]就是取该字符串的第一个字符'4',其ASCII值为52。
  • 后三个seldata元素正常:属于堆内存分配的巧合,溢出的字节刚好没覆盖到后三个指针的位置。

修复后的代码

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

#define START_COL 2
#define MID_COL 30

typedef struct{
    int datsize;
    int selsize;
    char** data;
    uint8_t** seldata;
}Screen;

static const char* HOME_SCREEN[7]={"Ruthless RFID","1.READ CARD","2.WRITE CARD","3.SHOW FILES","4.DISP","5.STATS","6.EXIT"};
static const uint8_t HOME_SEL[6][3]={{2,START_COL,2},{4,START_COL,2},{6,START_COL,2},{2,MID_COL+15,2},{4,MID_COL+15,2},{6,MID_COL+15,2}};

void SCREEN_INIT(Screen* screen){

    screen->datsize=7;
    screen->selsize=6;
    // 修正data的内存分配大小
    screen->data=(char**)malloc(screen->datsize * sizeof(char*));
    // 修正seldata的分配类型
    screen->seldata=(uint8_t**)malloc(screen->selsize * sizeof(uint8_t*));

    for(int i=0;i<screen->selsize;i++){
        screen->seldata[i]=(uint8_t*)malloc(3*sizeof(uint8_t));
        // 规范memcpy的字节数写法
        memcpy(screen->seldata[i],HOME_SEL[i],3 * sizeof(uint8_t));
        
    }
    memcpy(screen->data,HOME_SCREEN,sizeof(HOME_SCREEN));
}


int main(){
    Screen HOME;
    
    SCREEN_INIT(&HOME);
    printf("%i\n",HOME.seldata[0][0]); // 现在会输出预期的2
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 11:04:58