问题描述
在大多数情况下,它运行良好。例如,我压缩 3D 网格。几乎所有模型压缩\解压都很好。但是当程序尝试解压缩时,2 或 3 个模型可能会出错。解压好,但释放内存时出错
// how I read my files
u8* compressed_v = nullptr;
u8* compressed_i = nullptr;
if(!meshhead.m_dataComressSize_i)
{
YY_PRINT_Failed;
return nullptr;
}
if(!meshhead.m_dataComressSize_v)
{
YY_PRINT_Failed;
return nullptr;
}
compressed_v = (u8*)yyMemAlloc(meshhead.m_dataComressSize_v);
compressed_i = (u8*)yyMemAlloc(meshhead.m_dataComressSize_i);
in.read((char*)compressed_v,meshhead.m_dataComressSize_v);
in.read((char*)compressed_i,meshhead.m_dataComressSize_i);
u32 outsize = 0;
new_mesh.m_data->m_vertices = yyDecompressData(compressed_v,meshhead.m_dataComressSize_v,outsize,yyCompresstype::ZStd);
new_mesh.m_data->m_indices = (u8*)yyDecompressData(compressed_i,meshhead.m_dataComressSize_i,yyCompresstype::ZStd);
...
yyMemFree(compressed_v);
yyMemFree(compressed_i); // ERROR HERE
yyMemAlloc
和 yyMemFree
只是来自 malloc
free
和 mylib.dll
现在是 ZStd 代码。请检查。
u8* Engine::compressData_zstd( u8* in_data,u32 in_data_size,u32& out_data_size)
{
u8* out_data = (u8*)yyMemAlloc(in_data_size); // malloc
if( !out_data )
{
YY_PRINT_Failed;
return nullptr;
}
auto compressBound = ZSTD_compressBound(in_data_size);
size_t const cSize = ZSTD_compressCCtx( m_cctx,out_data,compressBound,in_data,in_data_size,1);
if( ZSTD_isError(cSize) )
{
yyMemFree(out_data); // free
return nullptr;
}
//yyMemRealloc(out_data,(u32)cSize); // this give errors so I removed it
out_data_size = (u32)cSize;
return out_data;
}
u8* Engine::decompressData_zstd( u8* in_data,u32& out_data_size)
{
unsigned long long const rSize = ZSTD_getFrameContentSize(in_data,in_data_size);
u8* out_data = (u8*)yyMemAlloc((u32)rSize);
if( !out_data )
{
YY_PRINT_Failed;
return nullptr;
}
size_t const dSize = ZSTD_decompress(out_data,(size_t)rSize,in_data_size);
out_data_size = (u32)dSize;
return out_data;
}
或者 ZStd 代码很好,但其他地方有问题?
它看起来像 yyMemAlloc
和 yyMemFree
中的问题,但它只是 malloc
和 free
,我在不同的模块(.exe 和许多 .dll)中随处使用它,并且一切正常。
解决方法
如果 in_data
不可压缩,则需要表示的内容超过 in_data_size
。
顺便说一下,实际最坏情况的计算值是 compressBound
。
因此为 compressBound
分配 out_data
字节,而不是 in_data_size
。