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

如何不改动原有代码,高效检查经memset初始化的结构体是否被修改

解决方案

因为无法修改原有结构体定义和初始化逻辑,核心判断逻辑基于「对比目标结构体内存和全零模板是否完全一致」,memset会把结构体包括对齐填充位在内的所有内存都置为0,所以直接对比整块内存即可,不需要单独校验每个成员。

方案1:通用标准实现(优先推荐)

兼容性最好,不需要适配平台,性能足够覆盖99%的使用场景:

#include <string.h>

// 传入要校验的结构体指针,返回1表示仍为全零初始状态,0表示被修改过
int is_teststruct_unmodified(const teststruct *obj) {
    // 静态存储期的结构体默认全零初始化,和memset置零结果完全匹配
    static const teststruct zero_template;
    return memcmp(obj, &zero_template, sizeof(teststruct)) == 0;
}

说明:

  • 静态变量zero_template只会在程序启动时初始化一次,没有额外运行时开销
  • 主流编译器会对memcmp做高度优化,小尺寸结构体的对比会直接展开为寄存器操作,没有函数调用开销,大尺寸结构体也会自动调用向量指令加速。

方案2:手动优化实现(仅适用于超大结构体极端性能需求)

如果结构体尺寸非常大(比如几MB级别),可以手动按机器字长对比进一步压榨性能:

#include <stdint.h>

int is_teststruct_unmodified_fast(const teststruct *obj) {
    size_t remain_size = sizeof(teststruct);
    // 先按64位字长对比,适配64位平台
    const uint64_t *p64 = (const uint64_t *)obj;
    while (remain_size >= sizeof(uint64_t)) {
        if (*p64++ != 0) {
            return 0;
        }
        remain_size -= sizeof(uint64_t);
    }
    // 剩余不足8字节的部分按字节对比
    const uint8_t *p8 = (const uint8_t *)p64;
    while (remain_size > 0) {
        if (*p8++ != 0) {
            return 0;
        }
        remain_size--;
    }
    return 1;
}

说明:该实现依赖结构体首地址满足机器字长对齐要求,C标准要求结构体变量的首地址默认满足最大基本成员的对齐要求,所以正常使用不会出现内存访问异常。

注意事项

  • 不要单独对比每个结构体成员,不仅开发成本高,还会漏掉结构体对齐填充位的校验,无法检测到填充位被意外修改的场景
  • 两种实现都不需要修改原有历史代码,只需要新增校验函数即可直接调用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 15:36:00