C ++向量读取访问冲突Mylast返回0x8

时间:2016-10-23 18:13:26

标签: c++ vector access-violation

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

编辑:

你们很多人都说我需要使用调试器,但让我明白我已经很长时间没有使用过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获取函数以检查它们是否导致了问题。

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

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

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

这是Draw和创建Sprite函数

 // 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函数中添加了一些测试代码,以检查精灵是否也被添加到矢量列表中。它返回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;


 };

1 个答案:

答案 0 :(得分:2)

我不会轻易说出来,但你展示的代码绝对可怕。在理解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 vs new [] / delete []:

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

这会导致未定义的行为:this->render未定义,并且非新[]分配上的delete[]未定义。

大多数程序员使用命名约定来区分成员变量和局部变量。两种常见做法是成员的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_() {}