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

使用std::unique_ptr<uint8[]>存储纹理数组,复制后数据错乱如何解决?

问题分析与修复方案

核心错误点

  • 错误1:手动释放智能指针管理的偏移指针
    你调用delete Ptr;和delete PartPtr;是完全错误的:

    1. Ptr的所有权属于std::unique_ptr<uint8[]>,unique_ptr会在自身生命周期结束时自动释放内存,手动delete会触发双重释放,引发未定义行为。
    2. 循环结束后,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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 08:40:35