C++:损坏的双链表和内存损坏
C++: corrupted double-linked list and memory corruption
我知道这个问题在stackoverflow中有答案,但我仍然无法解决我的问题,我没有看到错误。我正在使用vector,我认为我使用它是正确的,我没有做任何免费或malloc/calloc之类的事情。然而,我确信问题出在向量上,做了一些错误的事情。最奇怪的部分是对程序进行调试,它出现在两三个不同的站点。
我在linux上使用SDL2和默认的gcc编译代码。我正在使用Netbeans,使用命令
g++ -std=c++11 -g -Wall -c -g -MMD -MP -MF "path/src/game/Game.o.d" -o path/src/game/Game.o src/game/Game.cpp
并与-lSDL2-lSDL2_image 链接
错误,其中一个
malloc(): memory corruption (fast): 0x0000000000d86d50 ***
corrupted double-linked list: 0x00000000013fb5d0 ***
或不太常见:[link][1]
Valgrind展示了这样的东西,但我不知道如何使用:[link][2]
我把最重要的代码放在这里,但我把完整的项目留给你,看看你是否愿意。希望你能帮我。我不确定是我做错了什么,还是问题出在其他方面。
【项目链接】[3]
主要.cpp
#include ... //some includes
using namespace std;
Shape* shape;
TableBoard board;
Square* square;
Command* command;
void keyDown(SDL_Event &evento) {
if (evento.type == SDL_KEYDOWN) {
SDL_Keycode key = evento.key.keysym.sym;
command = nullptr;
switch (key) {
case SDLK_LEFT:
command = new LeftRight(board, *shape, Direction::LEFT);
shape->addCommand(command);
break;
case SDLK_RIGHT:
command = new LeftRight(board, *shape, Direction::RIGHT);
shape->addCommand(command);
break;
case SDLK_DOWN:
command = new FallToGround(board, *shape);
shape->addCommand(command);
break;
case SDLK_ESCAPE:
exit(0);
}
}
}
void newShape() {
if (shape == nullptr || !shape->isCanFall()) {
shape = new LShape(*square);
board.addShape(shape);
shape->setCanFall(true);
Command* command = new Fall(board, *shape);
shape->addCommand(command);
}
}
int main(int argc, char** argv) {
Window pantalla;
SDL_Event evento;
board = TableBoard(pantalla.getWindow(), 20, 10);
Board meassureBoard = board.getMeassureBoard();
SDL_Texture* image = IMG_LoadTexture(pantalla.getPantalla(),
"resources/images/blue_bold.png");
//creo una celda, le paso datos de table y que él se pinte
square = new Square();
square = new Square();
square->setGraphics(meassureBoard, image);
square->setX(3);
square->setY(1);
bool letsQuit = false;
Timer timer{};
timer.start();
newShape();
while (!letsQuit) {
pantalla.clear();
shape->executeCommands();
shape->clearCommandsFinished();
board.paint(pantalla.getPantalla());
board.drawLines(pantalla.getPantalla());
pantalla.actualizar();
while (SDL_PollEvent(&evento)) {
if (evento.type == SDL_QUIT) { // Si es de salida
letsQuit = true;
} else {
keyDown(evento);
}
}
newShape();
if (timer.delta() < 16) {
SDL_Delay(16 - timer.delta());
}
timer.restart();
}
return 0;
}
形状的一部分(LShape的父类)
void Shape::executeCommands() {
for(vector<Command*>::iterator it = commands.begin(); it != commands.end(); ++it) {
(*it)->execute();
}
}
void Shape::clearCommandsFinished() {
vector<int> remove;
int index=0;
for(vector<Command*>::iterator it = commands.begin(); it != commands.end(); ++it) {
if ((*it)->isAlive() != true) {
remove.push_back(index);
}
index++;
}
for(vector<int>::iterator it = remove.begin(); it != remove.end(); ++it) {
commands.erase(commands.begin()+(*it));
}
}
Fall命令的一部分,左侧和右侧类似。这里给出错误
void Fall::execute() {
if (isAlive() && timer.delta() >= milisecondsFalling) {
timer.restart();
bool canMove = true;
vector<Square> squares = shape->nextMove(0, 1);
if (shape->isCanFall()) {
int number=shape->getNUMBER_OF_SQUARES();
for (int i = 0; i < number && canMove; i++) {
//check the range
if (squares[i].getX() < 0
|| squares[i].getX() > board.getNumberColumns() - 1
|| squares[i].getY() < 0
|| squares[i].getY() > board.getNumberRows() - 1) {
canMove = false;
} else {
if (board.isFilled(shape, squares[i])) {
canMove = false;
}
}
}
//if we can move, move it definitively
if (canMove) {
shape->move(0, 1);
board.updateBoard();
}else{
shape->setCanFall(false);
}
} else {
alive = false;
} //-> AT THIS EXACTLY MOMENT GIVE THE ERROR!! NOT AFTER, NOT BEFORE
}
}
不重要,但这里也有错误。窗口类的部件
void Window::actualizar() {
// Mostramos la pantalla
SDL_RenderPresent(renderer); //EXACTLY POINT WHERE THROW THE ERROR, less frecuent
}
void Window::inicializacion() {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
cout << "No se pudo iniciar SDL: " << SDL_GetError() << endl;
exit(1);
}
atexit(SDL_Quit);
pantalla = SDL_CreateWindow("Tetris", //CREATED AS PRIVATE IN HEADER INSIDE CLASS: SDL_Window *pantalla;
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
window.w, window.h,
0);
renderer = SDL_CreateRenderer(pantalla, -1, SDL_RENDERER_ACCELERATED);
this->clear();
if (pantalla == NULL) {
cout << "Error iniciando el entorno gráfico: " << SDL_GetError() << endl;
exit(1);
}
this->pantalla=pantalla;
}
Window::Window() {
window.w=1024;
window.h= 768;
inicializacion();
}
编辑:链接已删除。问题已解决
我不会去调试整个事情(这对我们任何一个人来说都是毫无成效的)。我对您的源库进行了简短的查看,发现了以下内容:
vector<Square> Shape::nextMove(int x, int y)
{
//make a copy to not really moving the squares
vector<Square> clone(numberSquares);
for (int i = 0; i <= numberSquares; i++) { // <<=== HERE
clone[i] = *(new Square(squares[i]));
}
//get the next move
moveShape(clone, x, y);
//return the modified squares
return clone;
}
<=
的索引超过了源向量和目标向量的大小,即BAD。更糟糕的是,for循环中的代码是公然的内存泄漏。整个功能应该简化为:
vector<Square> Shape::nextMove(int x, int y)
{
vector<Square> clone = squares;
moveShape(clone, x, y);
return clone;
}
祝好运
相关文章:
- 如何针对特定情况调试和修复此双自由内存损坏问题
- 正在调试 malloc():新内存损坏
- 仅特定内核计数上的 MPI 内存损坏
- C++程序错误:malloc():内存损坏
- 内存地址是否由于未对齐的内存地址而损坏?
- 调用std::函数成员时内存损坏
- 通过分配大量内存来跟踪堆损坏
- C++ 内存损坏检测
- 由于标头中的 #define 不匹配而导致内存损坏
- C STD ::线程中的种族状况或内存损坏
- malloc()内存损坏仅通过为特定数量编写int数组
- 字符串标记化期间的内存损坏
- 从检测到 glibc 正常退出 - malloc():内存损坏
- 放置在外部 DLL 中的类中的字符串数据的内存损坏
- std :: string ::擦除会导致内存损坏
- 编译器如何检测内存损坏
- 获得MAC地址的代码似乎会损坏内存,但仅在发布构建中而不是调试构建
- Visual Studio在使用sockaddr_storage时会损坏内存
- 构造函数中的字段初始化会损坏内存
- 字符串结束字符会损坏内存吗?缓冲区[大小]='\0';