c++ Vector读访问冲突Mylast返回0x8

C++ Vector read access violation Mylast returned 0x8

本文关键字:返回 0x8 Mylast 访问冲突 Vector c++      更新时间:2023-10-16

我真的需要帮助,因为我非常卡住,不知道该怎么做。

编辑:

你们很多人都说我需要使用调试器,但让我澄清一下,我已经很长时间没有使用c++了,我使用visual studio总共只有2周,所以我不知道它可以用调试器做什么。

我是一名大学二年级刚开始的学生,我试图弄清楚如何做一件事,大部分是失败的。

我不是一个专业的程序员,当涉及到这些问题时,我不具备你们所拥有的所有知识,这就是我问这个问题的原因。我正在尽我最大的努力来展示我的问题,所以是的,我的代码包含很多错误,因为我对很多c++原则只有非常基本的了解,所以你在注释

时能记住这一点吗?

我只是在这里发布这个,因为我不知道现在还可以问谁。

我有一个名为world的函数,它应该调用我的渲染类来绘制其向量内的所有对象到屏幕。

#include "C_World.h"
C_World::C_World()
{
// creates an instance of the renderer class to render any drawable objects 
C_Renderer *render = new C_Renderer;
}

C_World::~C_World()
{
delete[] render;
}
// adds an object to the world vector 
void C_World::addToWorld(C_renderable* a) 
 {
world_list.push_back(a);
  }

 void C_World::World_Update()
{
render->ClearScreen();
World_Render();
}

void C_World::World_Render() {
for (int i = 0; i < 1; i++)
{
    //render->DrawSprite(world_list[i]->getTexture(), world_list[i]->get_X,  world_list[i]->get_Y());
    render->DrawSprite(1, 1, 1);
}
}

在测试时,我注释了Sprites get函数,以检查它们是否导致了问题。

通过create Sprite函数将渲染器精灵添加到构造函数中的向量列表中

C_Renderer::C_Renderer()
{
// test sprite: Id = 1
CreateSprite("WhiteBlock.png", 250, 250, 1);
}

我认为这可能是问题所在,所以我在其他函数中使用了它,但这并没有解决任何问题

下面是绘制和创建精灵函数

 // Creates a sprite that is stored in the SpriteList
 // Sprites in the spriteList can be used in the drawSprite function
 void C_Renderer::CreateSprite(std::string texture_name,
 unsigned int Texture_Width, unsigned int Texture_height, int spriteId) 
 {
 C_Sprite *a = new C_Sprite(texture_name,Texture_Width,
 Texture_height,spriteId);
 SpriteList.push_back(a);
 size_t b = SpriteList.size();
 HAPI.DebugText(std::to_string(b));
 }
// Draws a sprite to the X and Y co-ordinates
void C_Renderer::DrawSprite(int id,int x,int y)
 {
 Blit(screen, _screenWidth, SpriteList[id]->get_Texture(), 
 SpriteList[id]->getTexture_W(), SpriteList[id]->getTexture_H(), x, y);
 }

我甚至在create sprite函数中添加了一些测试代码,以检查sprite是否被添加到矢量列表中。它返回1,所以我假设它是。

Exception thrown: read access violation.
std::_Vector_alloc<std::_Vec_base_types<C_Sprite *,
std::allocator<C_Sprite     *> > >::_Mylast(...) returned 0x8.

这是我从编译器得到的全部错误

我真的真的卡住了,如果你还需要什么信息,就说一声,我会马上贴出来的

编辑2:

 #pragma once
 #include <HAPI_lib.h>
 #include <vector>
 #include <iostream>
 #include "C_renderable.h"
 #include "C_Renderer.h"
class C_World
{
public:
C_World();
~C_World();
C_Renderer *render = nullptr;
void World_Update();
void addToWorld(C_renderable* a);
private:
std::vector<C_renderable*> world_list;
void C_World::World_Render();

};

#pragma once
#include <HAPI_lib.h>
#include "C_renderable.h"
#include "C_Sprite.h"
#include <vector>
class C_Renderer
{
public:
C_Renderer();
~C_Renderer();
// gets a pointer to the top left of screen
BYTE *screen = HAPI.GetScreenPointer();
void Blit(BYTE *destination, unsigned int destWidth,
BYTE *source, unsigned int sourceWidth, unsigned int sourceHeight,
int posX, int posY);
void C_Renderer::BlitBackground(BYTE *destination,
unsigned int destWidth,   unsigned int destHeight, BYTE *source,
unsigned int sourceWidth, unsigned int   sourceHeight);
void SetPixel(unsigned int x,
unsigned int y, HAPI_TColour col,BYTE *screen,    unsigned int width);
unsigned int _screenWidth = 1750;
void CreateSprite(std::string texture_name, 
unsigned int Texture_Width,unsigned int Texture_height, int spriteId);
void DrawSprite(int id, int x, int y);
void ClearScreen();
private:
std::vector<C_Sprite*> SpriteList;

 };

我不是随便说的,但是您展示的代码确实很糟糕。在你对c++的理解中,你需要停下来回到几个层次。

很可能,你的崩溃是一个或多个函数中简单的"阴影"问题的结果:

C_World::C_World()
{
// creates an instance of the renderer class to render any drawable objects 
C_Renderer *render = new C_Renderer;
}
C_World::~C_World()
{
delete[] render;
}

这里有多个错误,并且您没有显示C_World的定义,但是如果这段代码可以编译,我们可以推断它有一个成员render,并且您已经陷入了一个常见的陷阱。

C_Renderer *render = new C_Renderer;

因为这一行以类型开始,这是一个新的局部变量render定义。您的编译器应该警告您,该遮蔽了同名的类作用域变量

这几行代码

C_World::C_World()
{
// creates an instance of the renderer class to render any drawable objects 
C_Renderer *render = new C_Renderer;
}

做的是:

. assign an undefined value to `this->render`,
. create a *local* variable `render`,
. construct a dynamic `C_Renderer` presumably on the heap,
. assign that to the *local* variable `render`,
. exit the function discarding the value of `render`.

所以此时内存不再被跟踪,它已经泄漏,并且this->render指向一个未定义的值。

您在几个函数中重复这个问题,将new结果分配给局部变量并且对它们不做任何事情。可能不是这个特定的实例导致了问题。

你的下一个问题是new/delete与new[]/delete[]的不匹配:

C_World::~C_World()
{
delete[] render;
}

这将导致未定义的行为:this->render是未定义的,delete[]在非new[]分配上是未定义的。

大多数程序员使用一种命名约定来区分成员变量和局部变量。两种常见的做法是为成员使用m_前缀或_后缀,例如

class C_World
{
public:
     C_Foo* m_foo;  // option a
     C_Renderer* render_;  // option b
// ...
}

也许你应该考虑使用现代c++的智能指针的概念:

#include <memory>
class C_World {
    // ...
    std::unique_ptr<C_Renderer> render_;
    // ...
};
C_World::C_World()
    : render_(new C_Renderer)   // initializer list
{}

但是不清楚为什么在这里首先使用动态分配。似乎实例成员会更好:

class C_World {
    C_Renderer render_;
};
C_World::C_World() : render_() {}