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
相关产品推荐
相关产品推荐

