我真的需要帮助,因为我非常困难,不知道该怎么做。
编辑:
你们很多人都说我需要使用调试器,但让我明白我已经很长时间没有使用过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;
};
答案 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_() {}