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

LZMA SDK C解压时inProcessed值异常增大的问题咨询

LZMA SDK解压时inProcessed异常增大的问题解决

核心问题:参数传递错误

你的示例代码中调用LzmaDec_DecodeToBuf时,错误地传递了outProccessed和inProcessed的值,而非指针。LZMA SDK的这个函数要求这两个参数是指针类型,用于输出实际处理的字节数:

  • 第三个参数size_t *outProcessed:传入缓冲区的最大容量,函数返回时修改为实际写入的字节数
  • 第五个参数size_t *inProcessed:传入输入缓冲区的可用字节数,函数返回时修改为实际消耗的字节数

如果直接传值,函数内部会修改临时副本,你看到的inProcessed值是未定义的垃圾数据(比如36),这是内存访问错误导致的异常,和LZMA解压逻辑无关。

正确的调用方式应该是:

static uint8_t storage_buffer[2000];

size_t outProcessed = 2000;
size_t inProcessed = 32;
LZMA_STATUS status;
SRes res;

res = LzmaDec_DecodeToBuf(state, storage_buffer, &outProcessed, input_buffer, &inProcessed, finishMode, &status);

其他可能的原因与处理逻辑

如果修正参数传递后仍出现inProcessed异常增大的情况,需要从以下方面排查:

1. 解压状态未正确初始化

如果复用了LzmaDec结构体(state)但未重置状态,解码器会保留上一次解压的残留状态,导致它错误地期望读取更多输入数据。

  • 解决:每次开始新的解压任务时,必须调用LzmaDec_Init(state)重置状态;如果是分块解压同一数据流,需要确保状态的连续性。

2. 错误判断返回值与状态

不能仅通过inProcessed的大小判断结果,必须结合返回值res和status参数:

  • 若res == SZ_OK:
    • status == LZMA_STATUS_FINISHED_WITH_MARK / LZMA_STATUS_FINISHED_NO_MARK:解压完成,此时inProcessed应等于传入的初始值(输入数据刚好被完全消耗)
    • status == LZMA_STATUS_NEEDS_MORE_INPUT:需要更多输入数据,此时inProcessed应等于初始值(已消耗所有提供的输入),需补充输入后继续解压
  • 若res != SZ_OK:
    • SZ_ERROR_DATA:压缩数据损坏,解码器无法正确解析
    • SZ_ERROR_INPUT_EOF:输入数据提前结束,解码器需要更多数据才能完成解压
      这两种情况出现时,inProcessed的异常值说明解码器尝试读取超出可用输入的范围,应视为解压失败,终止流程并处理错误。

3. finishMode参数设置错误

finishMode决定解码器是否认为输入已经结束:

  • 若设为LZMA_FINISH_END:解码器会强制检查输入是否完全结束,若输入不足会返回错误
  • 若设为LZMA_FINISH_ANY:解码器会尽可能处理输入,直到缓冲区满或输入结束
  • 若设为LZMA_FINISH_NONE:解码器不会检查输入是否结束,适合分块解压
    确保finishMode的设置与你的解压场景匹配,避免解码器错误地期望更多输入。

修正后的示例逻辑

static uint8_t storage_buffer[2000];

size_t outProcessed = 2000;
size_t inProcessed = 32;
LZMA_STATUS status;
SRes res;

res = LzmaDec_DecodeToBuf(state, storage_buffer, &outProcessed, input_buffer, &inProcessed, finishMode, &status);

if (res == SZ_OK) {
    if (status == LZMA_STATUS_FINISHED_WITH_MARK || status == LZMA_STATUS_FINISHED_NO_MARK) {
        // 解压完全完成,所有输入都被处理
        if (inProcessed == 32) {
            return 0;
        }
    } else if (status == LZMA_STATUS_NEEDS_MORE_INPUT) {
        // 已消耗所有输入,需要补充更多数据继续解压
        // 处理未完成的逻辑,比如保存当前状态,获取新的输入缓冲区
    }
} else {
    // 解压错误,处理异常(数据损坏、输入不足等)
    if (inProcessed > 32) {
        // 解码器尝试读取超出可用输入的范围,属于错误情况,直接返回失败
        return -1;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 18:46:12