我该如何解决这个问题? " HEAP CORRUPTION DETECTED after normal block.. CRT detected that the application wrote



我有一个使用引用的程序运行良好(没有提示错误(,但我决定使用分配在虚拟内存上的指针到指针数组,因为我可以使用变量作为数组的大小。

当我中断while (m_Window.isOpen())循环时,也就是说,当我关闭游戏窗口并且游戏结束时,会出现错误提示。我注意到,当我试图擦除Engine::cleanVirtualMemory()函数中的虚拟内存时,程序会中断。我注意到它在那里,因为我放置了两个标志(cout << "running1" << endl;cout << "running2" << endl(,并且我可以只显示第一个标志。

然后,它会提示一个窗口,显示以下消息:

正常块后检测到HEAP腐蚀。。CRT检测到应用程序在堆缓冲区结束后写入内存

main.cpp

#include "Engine.h"
using namespace sf;
int main(){
Engine Motor;
Motor.run();
Motor.cleanVirtualMemory();
}

发动机.h

#pragma once
#include <SFML/Graphics.hpp>
#include "StructureBuilder.h"
using namespace sf;
using namespace std;
class Engine{
private:
// Lots of variables ....
Vector2i m_ArenaSize;
Vector2f * vectorStructureArray = new Vector2f[m_ArenaSize.y * m_ArenaSize.x * 4];
int** logicStructureArray = new int*[m_ArenaSize.y];
// Lots of variables ....
//Gameloop
void Input();
void Update(dtAsSeconds);
void Draw();
public:
Engine();
void run();
void cleanVirtualMemory();
};

Engine.cpp

#include "Engine.h"
#include <iostream>
using namespace sf;

Engine::Engine() {
/// lots of variables and data ...
/// Making arena
m_ArenaSize = Vector2i(10, 10);
StructureBuilder(arenaStructures, vectorStructureArray, logicStructureArray,  m_ArenaSize);
}

void Engine::run() {
//Timing
Clock clock;
while (m_Window.isOpen()) {
// Each time clock restarted, dt = time elapse (from 0 to now, then clock = 0)
Time dt = clock.restart();
// Convert time elapse to seconds
double dtAsSeconds = dt.asSeconds();

//  Call each part of the game in turn
Input();
Update(dtAsSeconds);
Draw();
}
}
void Engine::cleanVirtualMemory() {
// Deallocate Virtual Memory

// first flag
cout << "running1" << endl;
for (int i = m_ArenaSize.x - 1; i > -1; i--) {
delete[] logicStructureArray[i];
}
delete[] logicStructureArray;
logicStructureArray = NULL;
delete[] vectorStructureArray;
vectorStructureArray = NULL;
// second flag
cout << "running2" << endl;
}

StructureBuilder.h

#pragma once
#include <SFML/Graphics.hpp>
#include <iostream>
#include <string.h>
using namespace sf;
using namespace std;
Vector2i StructureBuilder(VertexArray& rVA, Vector2f* rA, int** rLA, Vector2i ArenaSize);

在下面的代码中,你可以看到我在哪里使用指针,我删除了代码只是为了简化。

StructureBuilder.cpp

#include "StructureBuilder.h"
Vector2i StructureBuilder(VertexArray& rVA, Vector2f* rA, int** rLA, Vector2i ArenaSize) {
//Set map properties and VertexArrayType
double tileSize = 100;
double Height = ArenaSize.y * tileSize;
double angle = 30;
int offset = 0;
int Primitive = 4;
int currentVertex = 0;
rVA.setPrimitiveType(Quads);
rVA.resize(ArenaSize.x * ArenaSize.y * 4);
// First build graphically our map structures's using char strings 
string stringArray[10]; 
stringArray[0] = "1000000000";
stringArray[1] = "0000000000";
stringArray[2] = "0000010000";
stringArray[3] = "0000000000";
stringArray[4] = "0000000000";
stringArray[5] = "0000000000";
stringArray[6] = "0000000000";
stringArray[7] = "0000000000";
stringArray[8] = "0000000000";
stringArray[9] = "0000000000";
// Convert stringArray to charArray, finally charArray to intArray
char** charArray = new char*[ArenaSize.y]; 
Vector2f Vector1;
Vector2f Vector2;
Vector2f Vector3;
Vector2f Vector4;
for (int i = 0; i < ArenaSize.x; i++) {
charArray[i] = new char[ArenaSize.x];
rLA[i] = new int[ArenaSize.x];

}
for (int i = 0; i < ArenaSize.x; i++) {
for (int j = 0; j < ArenaSize.y; j++) {
charArray[j][i] = stringArray[j][i];
rLA[j][i] = charArray[j][i] - 48;
// Check when we have a value greater or equal to 1, if yes build a structure.
if (rLA[j][i] == 1) {

Vector1 = Vector2f(Value..., Value...);// in order to understand I dont put the whole calculation here
Vector2 = Vector2f(Value..., Value ...); // is just trigonometry to find vertex
Vector3 = Vector2f(Value..., Value ...);
Vector4 = Vector2f(Value..., Value ...);

rVA[currentVertex + 0].position = Vector1;
rVA[currentVertex + 1].position = Vector2;
rVA[currentVertex + 2].position = Vector3;
rVA[currentVertex + 3].position = Vector4;
rVA[currentVertex + 0].texCoords = Vector2f(42, 0); // coords on my spritesheet
rVA[currentVertex + 1].texCoords = Vector2f(86, 24);
rVA[currentVertex + 2].texCoords = Vector2f(42, 49);
rVA[currentVertex + 3].texCoords = Vector2f(0, 24);
rA[currentVertex + 0] = Vector1; //Later I use this to tell the program where to construct restrictions (where the player can't move)
rA[currentVertex + 1] = Vector2;
rA[currentVertex + 2] = Vector3;
rA[currentVertex + 3] = Vector4;
}

currentVertex = currentVertex + Primitive;
}
}
// Deallocate Virtual Memory
for (int i = ArenaSize.x - 1; i > -1; i--) {
delete[] charArray[i];
}
delete[] charArray;
charArray = NULL;

return ArenaSize;
}

让我们来看看Engine类的声明。

class Engine{
private:
// Lots of variables ....
Vector2i m_ArenaSize;
Vector2f * vectorStructureArray = new Vector2f[m_ArenaSize.y * m_ArenaSize.x * 4];

Engine类的第一个成员称为m_ArenaSize。这是构造Engine时将构造的第一个类成员。这就是C++中对象构造的工作原理:当构造一个新对象时,该新对象的所有成员都将按声明顺序构造。

Engine类的第二个成员就是这个vectorStructureArray指针。它将被分配指向一个具有动态大小的数组,该数组使用构造的m_ArenaSize自己的两个成员xy来获取newed。

现在,让我们来看看Engine的构造函数:

Engine::Engine() {

好吧。那是你的建造师。因此,根据我们的计划,m_ArenaSize将得到默认构造,因为它不是显式构造的,在Engine的构造函数的初始化部分(这里没有(。如果您研究m_ArenaSize的默认构造函数的作用,您会发现它将xy默认为0。

这就是构造vectorStructureArray指针的方法,作为Engine默认初始化的第二阶业务。而且,因为它的xy是0,所以指针将指向总共0个值。

m_ArenaSize = Vector2i(10, 10);

直到现在,默认构建的m_ArenaSize才被一个不同的主题所取代,该主题具有不同的xy值。显示的代码清楚地期望指针被重新分配,以反映m_ArenaSize的新xy值,。然而,C++不能以这种方式工作。vectorStructureArray已经构建完成。它不会因为替换了不同的类成员而被重新构造。后续代码的假设是新的xy值,这会导致相当明显的内存损坏。

logicStructureArray也会出现同样的错误。

这只是所示代码中关于内存分配的前两个主要错误。有几种方法可以修复它们,但修复bug最简单的方法是从一开始就让它们在逻辑上不可能发生。如果从未使用过newdelete,则逻辑上不可能出现与它们相关的错误。现代C++代码很少使用newdelete,而是使用C++库的许多容器的服务。

这里,两个指针都可以简单地由std::vector替换,其resize()成员负责分配两个向量的大小。而且,作为额外的奖励,所有分配的内存都会自动释放,自动防止所有内存泄漏。

std::vector替换所有易出错的newdelete逻辑将修复所示代码中所有与内存相关的问题,您唯一需要确保的是向量是正确的resize((d。

相关内容

  • 没有找到相关文章

最新更新