在解构sf::Image数组时堆损坏



所以我试图在SFML中为sf::图像制作渐变过渡动画,我有一个小问题。

当我没有注释掉下面调用的函数时,当图像被解构时说

时,我在main()的末尾得到一个错误

"Windows触发了一个断点。这可能是由于腐败造成的堆的。"

发生这种情况的行包含代码GLCheck(glDeleteTextures(1, &Texture));
为什么会发生这种情况,为什么只有当CreateTransition()运行?

还有一个注意事项:当我注释掉aray[I] = aray[0]时,break不会发生。
我把函数贴在下面。

void CreateTransition(sf::Image& start, sf::Image animationArray[numbImgs]){
    animationArray[0] = start;
    void threadFunc(void* imgArray);
    sf::Thread thread(threadFunc, reinterpret_cast<void*>(animationArray));
    thread.Launch();
    thread.Wait();     // comment this out once I get the code working
}
void threadFunc(void* ptr){
    sf::Image* aray = reinterpret_cast<sf::Image*> (ptr); 
    sf::Color filter(0, 0, 0, 5);
    for(int I= 1; I< numbImgs; I++){
        //aray[I].Copy(aray[0], 0, 0, sf::IntRect(0, 0, 0, 0), true);
        aray[I] = aray[0]; // error doesn't occur when commented out
        RecolorImage(aray[I], filter); 
    }
}
Image& Image::operator =(const Image& Other)
{
    Image Temp(Other);
    std::swap(myWidth,             Temp.myWidth);
    std::swap(myHeight,            Temp.myHeight);
    std::swap(myTextureWidth,      Temp.myTextureWidth);
    std::swap(myTextureHeight,     Temp.myTextureHeight);
    std::swap(myTexture,           Temp.myTexture);
    std::swap(myIsSmooth,          Temp.myIsSmooth);
    std::swap(myNeedArrayUpdate,   Temp.myNeedArrayUpdate);
    std::swap(myNeedTextureUpdate, Temp.myNeedTextureUpdate);
    myPixels.swap(Temp.myPixels);
    return *this;
}

以下几点可以帮助你缩小原因范围:

  • 堆损坏很少发生在程序崩溃时,这使得它们难以追踪。它可能与崩溃点的对象有关,也可能是另一个对象/代码损坏了它。
  • CreateTransition()中,您通过值传递animationArray[],但随后将其传递到线程过程中。当您从CreateTransition()返回时,animationArray[]的生命周期结束,这意味着如果线程过程在此之后运行,其void* ptr参数将不会指向有效对象。您在当前代码中确实有thread.Wait(),但也有关于删除它的注释。要么通过引用传递animationArray[],除非有特殊的原因,要么为线程过程创建一个临时副本,以确保它在有效的对象上操作。
  • 考虑使用std::vector<sf::Image>而不是数组。
  • 确保您理解并实现sf::image和任何依赖类(如MyPixels)的三规则。如果不这样做,可能会导致双重自由、内存泄漏和堆损坏,就像你看到的那样。
  • 如果所有其他方法都失败,尝试在临时测试项目中复制问题,并将其减少到尽可能少的代码量。每次清除一个sf::image的成员,直到问题消失。类似地,删除CreateTransition()中的行和线程过程中的其他行。你最终可能会得到一些非常具体的行来触发这个问题,或者是一个空项目。

最新更新