使用std::unique_ptr<uint8[]>存储纹理数组,复制后数据错乱如何解决?
问题分析与修复方案
核心错误点
错误1:手动释放智能指针管理的偏移指针
你调用delete Ptr;和delete PartPtr;是完全错误的:Ptr的所有权属于std::unique_ptr<uint8[]>,unique_ptr会在自身生命周期结束时自动释放内存,手动delete会触发双重释放,引发未定义行为。- 循环结束后,
Ptr和PartPtr已经指向数组的末尾(而非内存分配的起始地址),释放非起始地址的指针会直接破坏内存结构,导致数据错乱、程序崩溃等随机问题。
错误2:循环计数器类型不匹配
循环变量i是int类型,但循环条件中的计算值是SIZE_T(无符号整数类型)。当纹理尺寸较大时,计算结果可能超出int的取值范围,导致循环提前终止或越界访问,进而出现数据异常。
修复后的代码
推荐使用std::copy完成数组复制,既安全又高效:
SIZE_T PartBufferSize = WorldTextureWidth * WorldTextureHeight * DYNAMIC_TEXTURE_BYTES_PER_PIXEL; std::shared_ptr<uint8[]> PartPixelBuffer(new uint8[PartBufferSize]()); // 用std::copy替代手动循环,避免指针操作错误 std::copy(CPPPixelBuffer.get(), CPPPixelBuffer.get() + PartBufferSize, PartPixelBuffer.get());
如果坚持使用手动循环,需修正计数器类型并移除错误的delete:
SIZE_T PartBufferSize = WorldTextureWidth * WorldTextureHeight * DYNAMIC_TEXTURE_BYTES_PER_PIXEL; std::shared_ptr<uint8[]> PartPixelBuffer(new uint8[PartBufferSize]()); uint8* Ptr = CPPPixelBuffer.get(); uint8* PartPtr = PartPixelBuffer.get(); // 使用SIZE_T类型计数器,避免类型不匹配问题 for (SIZE_T i = 0; i < PartBufferSize; i++) { *(PartPtr++) = *(Ptr++); } // 绝对不要手动delete智能指针管理的指针!
内容的提问来源于stack exchange,提问作者Schrello
相关产品推荐
相关产品推荐

