std::vector导致指针无效
Pointer Invalidation with std::vector
我正在编写玩具C++代码来学习它和游戏开发,一路上包装SDL;它现在所做的就是加载一个BMP图像并在屏幕上循环显示。仅过帐相关代码。
编辑:我将把这篇文章修改到MVCE。这个问题可以更直接地找到。
#include <SDL.h>
#include <vector>
class Surface {
public:
Surface(SDL_Surface*);
~Surface();
SDL_Surface* mSurface;
}
Surface::Surface(SDL_Surface* surface) {
mSurface = surface;
}
Surface::~Surface() {
SDL_FreeSurface(mSurface);
}
int main(int argc, char* args[])
{
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
throw("Failed to SDL_Init: " + std::string(SDL_GetError()));
}
SDL_Window* window = SDL_CreateWindow("SDL TEST", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 960, SDL_WINDOW_SHOWN);
SDL_Surface* screenSurface = SDL_GetWindowSurface(window);
const char * imgPath = "test.bmp";
std::vector<Surface> surfaces;
surfaces.push_back(Surface(SDL_LoadBMP(imgPath)));
SDL_BlitSurface(surfaces.begin()->mSurface, // memory access violation here
NULL, screenSurface, NULL);
SDL_UpdateWindowSurface(window);
SDL_Delay(2000);
SDL_Quit();
return 0;
}
归根结底,加载到vector
中的Surface
对象内部的指针变为无效。我四处阅读,认为这可能与需要一个自定义副本构造函数有关,但制作这样的构造函数并不能解决问题:
Surface::Surface(const Surface& other) {
mSurface = other.mSurface;
mIsWindowSurface = other.mIsWindowSurface;
}
您没有定义复制构造函数,所以使用了默认的复制构造函数,但这并不能满足您的要求。
在线
surfaces.push_back(Surface(SDL_LoadBMP(imgPath)));
情况如下:
- 创建一个临时
Surface
,其mSurface
指向新分配的曲面 - 使用复制构造函数(或复制赋值运算符)将此
Surface
复制到向量中 - 破坏调用
SDL_FreeSurface
的临时Surface
然后,当您继续执行surfaces.begin()->mSurface,
时,您正在尝试使用已经释放的曲面。
要在C++11之前解决此问题,您需要使复制构造函数和复制赋值运算符在语义上进行复制,或者使用引用计数机制来确保只有在没有更多指向曲面的活动指针时才调用SDL_FreeSurface
。
在C++11中,有更多开箱即用的修复程序;其中之一是禁用类的复制,并实现移动构造函数和移动赋值运算符,和/或使用emplace_back( SDL_LoadBMP
。。。而不是CCD_ 11。
相关文章:
- 在 C++ 中传递字符串时指针无效
- free():仅在一种情况下指针无效
- free():实现矢量擦除()时的指针无效
- free():添加字符串时指针无效
- C++ ecliipse free():函数末尾的指针无效
- C++ 指针无效函数问题
- 将 boost::object_pool 与矢量一起使用时指针无效
- free():矢量 C++ 的指针无效<vec4i>
- omnet++free():指针无效,错误134/139
- 在OpenCV中调用stereoRectify会导致异常:帧指针无效
- 销毁和重新创建一个对象会使指向该对象的所有指针无效吗
- 用户定义类中的Null指针无效
- 删除指向类的指针无效
- 运行GTest时指针无效
- C++错误消息:指针无效
- 可以std::string reconfiguration使指向堆的指针无效
- 为什么删除指向指针向量的指针会导致指针无效
- MPI_scatter:缓冲区指针无效
- mmap 错误:分段错误/指针无效错误
- 返回 std::string 时指针无效(libc 如此说)