I have followed a dirextX 9 tutorial on utube and i have tried to modify the program to display multiple triangles based on a set of points. I am using it as a sort of plotter. in my testing i generate a list of points within my plotter class. the plotter class then generates 3 vertices to create a small triangle around the point. the points are then passed to the directx device.
i have moved the code that generates the polygons into my update method, as i need to update the polygon list with fresh polygons.
The code works, but every now and then it will crash with the following error message
Unhandled exception at 0x010F6AF1 in DX3DPlotTest.exe: 0xC0000005: Access violation reading location 0x00000000.
im shure that the problem is to do with the memcpy command being called over and over. i've tried deleting pVert but that creates its own error as pVert is never initiated.
hear is my update version
`
void TestApp::Update(float dt)
{
void *pVerts;
plotter=new Plotter(MaxPoints,0.01f);
float x,y;
for(ULONG i=0;i<MaxPoints;i++)
{
x= (float)(distribution(generator)-2.0f);
y= (float)(distribution(generator)-2.0f);
plotter->Plot(x,y);
}
m_pDevice3D->CreateVertexBuffer(
plotter->listContentCount*sizeof(VertexPositionColor),
0,VertexPositionColor::FVF,
D3DPOOL_MANAGED,
&VB,
NULL
);
//d3d vertex buffer VB
VB -> Lock(0,sizeof(VertexPositionColor)*plotter->listContentCount, (void**)&pVerts, 0);
memcpy(pVerts,plotter->m_pVertexList,sizeof(VertexPositionColor)*plotter->listContentCount);
VB -> Unlock();
}
`
please can someone help me understand how to fix this problem? if been fiddling around with it for hours. It does work, but for a limited amount of time.
Thanks all.
EDIT:
OK now im shure its do to wich recreating my plotter instance
`
Plotter::Plotter(UINT PointCount,float pointsize)
{
listSize = PointCount*3;
listContentCount = 0;
bufferContentCount = 0;
Polycount = 0;
m_pStdtri = new VertexPositionColor[3];
m_pVertexList = new VertexPositionColor[listSize];
m_pStdtri[0] = VertexPositionColor(0.0f ,1.0f*pointsize ,d3dColors::Red);
m_pStdtri[1] = VertexPositionColor(1.0f*pointsize , -1.0f*pointsize ,d3dColors::Lime);
m_pStdtri[2] = VertexPositionColor(-1.0f*pointsize , -1.0f*pointsize ,d3dColors::Red);
}
Plotter::~Plotter()
{
delete(m_pStdtri);
delete(m_pVertexList);
}
void Plotter::Plot(float x, float y)
{
Polycount++;
m_pVertexList[listContentCount]=VertexPositionColor(x+m_pStdtri[0].x, y+m_pStdtri[0].y,d3dColors::Red);
listContentCount++;
m_pVertexList[listContentCount]=VertexPositionColor(x+m_pStdtri[1].x, y+m_pStdtri[1].y,d3dColors::Lime);
listContentCount++;
m_pVertexList[listContentCount]=VertexPositionColor(x+m_pStdtri[2].x, y+m_pStdtri[2].y,d3dColors::Blue);
listContentCount++;
}
`
There are a couple of things that can be wrong here. The plotter object seems to be never disposed, but it is potentially possible that it's done elsewhere. What bothers me, however, is your calling of CreateVertexBuffer over and over again, presumably without ever releasing the resource that you're using. So basically what happens in my opinion is: in every frame, you create a new VertexBuffer. As the memory on your GPU runs low, the command fails eventually, which you don't detect and try to use the "created" buffer, which is not really created. You need to know, that the buffer is not destroyed, even if you delete the object which holds the VB variable. The CreateVertexBuffer command occupies resources on GPU so they need to be explicitly freed when no longer needed. But let's return to the point. This function fails at some point. So it results in a NULL pointer error. My suggestion would be to create the buffer just once and then only update it in each frame. But first, make sure if it is the case.
Related
Greetings fellow programmers.
I've been struggeling with learning c++ within the Unreal engine. I thought I understood how to track time properly within a class but alas my variable is chaning it's contents to a vastly different number in the time between two function calls.
For context there are a small number of objects present:
Global Time system
This class is responsible for managing the time and receiving update ticks from the time watcher. This is also a singleton!
TimeWatcher
Super simple, just a Uobject I spawn into the world so it can receive update ticks from the engine and pass them onto the Global Time system
Time class
A class to hold the hours, minutes and seconds. How it is used beyond that is up to the developer using the class. In my case I am simply trying to store it and from that point on remove time off of it to create a countdown timer.
We have our own little logging system to help debugging along, mainly to generate logs without all the unreal stuff and in a format we prefer. This log outputs the following data:
<Log, TimerSystem> [2] 2019.03.17-17.41.42: init attempt, init time should be: 23:6.0
<Log, TimerSystem> [3] 2019.03.17-17.41.42: init attempt succes, 23:6.0
<Log, TimerSystem> [6] 2019.03.17-17.41.42: Timer tick occured, lets see what our timer thinks about the time -225161083:32766:00
So from this we can interpret that the variable in the scope it gets set in(shown below) is set there properly. But the moment we try to read it again in the handleTick function the variable is all wrong.
InitTimer function:
void GlobalTimerSystem::InitTimer(UWorld* world, Time* initialTime)
{
DebugUtility::WriteLog("init attempt, init time should be: " + initialTime->ToString(), DebugUtility::Log, DebugUtility::TimerSystem);
check(world);
//create timeWatcher in the world
FVector location(0.0f, 0.0f, 0.0f);
FRotator rotation(0.0f, 0.0f, 0.0f);
FActorSpawnParameters SpawnInfo;
world->SpawnActor<ATimeWatcher>(location, rotation, SpawnInfo);
//set current time to init value
Time* trPointer = new Time(initialTime->GetHours(), initialTime->GetMinutes(), initialTime->GetSeconds());
this->timeRemaining = *trPointer;
DebugUtility::WriteLog("init attempt succes, " + timeRemaining.ToString(), DebugUtility::Log, DebugUtility::TimerSystem);
}
There is some stupid pointer crap I am doing here, partly because of desperation at this point though.
The Handle tick function:
void GlobalTimerSystem::HandleTimerTick(float deltaTime)
{
DebugUtility::WriteLog("Timer tick occured, lets see what our timer thinks about the time " + timeRemaining.ToString(), DebugUtility::Log, DebugUtility::TimerSystem);
ticksReceived++;
FString debug2;
debug2.Append("Ticks received: ");
debug2.AppendInt(ticksReceived);
DebugUtility::WriteLog(debug2, DebugUtility::Log, DebugUtility::TimerSystem);
double t = static_cast<double>(deltaTime);
DecreaseTimer(&t);
if (deltaTime != NULL) {
FString debug;
debug.Append(TEXT("current time remaining is "));
debug.Append(*timeRemaining.ToString());
DebugUtility::WriteLog(debug, DebugUtility::Log, DebugUtility::TimerSystem);
}
}
Now we know things are already wrong the moment we enter the above function. For good measure here is the header file for this class.
class PGT_PROJECT_API GlobalTimerSystem
{
friend class ATimeWatcher;
private:
Time timeRemaining;
Time timeElapsedNotPaused;
Time timeElapsedPaused;
UINT ticksReceived = 0;
bool paused = false;
bool initComplete = false;
void HandleTimerTick(float deltaTime);
static GlobalTimerSystem* timerSystem;
public:
static GlobalTimerSystem* GetTimerSystem();
void InitTimer(UWorld* world, Time* initialTime);
void IncreaseTimer(double* additionalSeconds);
void DecreaseTimer(double* removeSeconds);
double GetTimeRemaining();
double GetTimeElapsed();
GlobalTimerSystem();
~GlobalTimerSystem();
};
If any more information is required I will be happy to provide. Thank you for your time!
EDIT:
I am overloading the Time::operator= which appears as follows:
Time & Time::operator=(Time & t)
{
_seconds = t._seconds;
_minutes = t._minutes;
_hours = t._hours;
return *this;
}
And using it as follows:
this->timeRemaining = Time(initialTime->GetHours(), initialTime->GetMinutes(), initialTime->GetSeconds());
However this results in the following compiler error that I do not understand:
Path...\Private\GlobalTimerSystem.cpp(62) : error C4239: nonstandard extension used: 'argument': conversion from 'Time' to 'Time &'
In GlobalTimerSystem::InitTimer(UWorld*, Time*), you do the following:
Time* trPointer = new Time(initialTime->GetHours(),
initialTime->GetMinutes(),
initialTime->GetSeconds());
this->timeRemaining = trPointer;
which means:
Create a new object of type Time on the heap, construct it with the following arguments and, once it's ready, return a pointer to it (Time*) which I'll store in my local variable trPointer;
assign the value of the pointer trPointer (which is the address of the instance of the class Time that we just allocated and initialized on the heap) to my instance variable timeRemaining (which is an instance of the class Time).
So once you reach GlobalTimerSystem::HandleTimerTick, this->timeRemaining contains garbage which stays garbage when translated ToString (hence the -225161083:32766:00 you see). Furthermore, the memory you now have allocated on the heap for that instance of Time you've created is wasted as you will never release it and won't even use it.
The thing is that, in this case, you don't need the heap at all!
Depending on how operator= behaves (you said you overloaded it), you should be able to do:
this->timeRemaining = Time(initialTime->GetHours(),
initialTime->GetMinutes(),
initialTime->GetSeconds());
which will create a temporary Time instance and initialize it with the passed arguments, then "copy" it (=) inside your instance variable timeRemaining. If you do this, you might want to look into Time::operator=(Time&&) as that "temporary Time instance" is an rvalue. Please note that, in this case, we do not leak memory as everything is allocated on the stack and will be released when the function returns.
If this does not work, that means Time::operator= is not behaving as a proper "copy operator" and should be fixed. Another approach would be to manually set the hours, minutes and seconds fields of timeRemaining (if they are public or friend) or (much better), to have a method such as Time::set(/*hours, minutes, seconds*/) allowing you to this->timeRemaining->set(...).
Finally, once again depending on the internals of Time and how Time::operator= has been written, noticing that initialTime is itself a Time*, the "temporary intermediate Time instance" shouldn't even be needed, leading to the much simpler and more readable
this->timeRemaining = *initialTime;
As a conclusion, I believe your issue comes from the implementation of Time::operator=.
I'm entirely new to SDL 2 , and I'm hoping to find some help with making my very first proper program for a class in it. We've been provided with some code already for use in this project, which is why I'm not simply using a BlitSurface function to make this solution. If that is indeed the better solution, I'll switch over to that. This is part of a State to be used when the program runs, showing a title image.
I am getting a break error due to a pointer issue in the following code:
void MenuState::Enter()
{
//Is to load the title image used for the State
Sprite* extBackgroundSprite = met_extSystem.met_pointextSpriteManager- >CreateSprite("../assets/Testimage1.bmp" , 0 , 0 , 768 , 1024);
}
Which refers to a Sprite made by a SpriteManager class and CreateSprite function, as seen here:
Sprite * SpriteManager::CreateSprite(const std::string & point_stringFilePath, int point_intX, int point_intY, int point_intWidth, int point_intHeight)
{
auto iter = met_arraypointextTextures.find(point_stringFilePath); //breaks here
if (iter == met_arraypointextTextures.end())
//If the iterator cannot locate the sprite we need in our already loaded memory,
//it needs to be loaded into our map to create pointers
{
SDL_Surface* extSurface = SDL_LoadBMP(point_stringFilePath.c_str());
SDL_Texture* extTexture = SDL_CreateTextureFromSurface(met_pointextRenderer, extSurface);
SDL_FreeSurface(extSurface);
met_arraypointextTextures.insert(std::pair<std::string, SDL_Texture*>(point_stringFilePath, extTexture));
iter = met_arraypointextTextures.find(point_stringFilePath);
}
//Creates the sprite, adds a new index point via pushback
Sprite* extSprite = new Sprite(iter->second, point_intX, point_intY, point_intWidth, point_intHeight);
met_arraypointextSprites.push_back(extSprite);
return extSprite;
}
I hope this is enough information and code to present my problem. If not, let me know! And thank you in advance.
Turns out the issue was impossible to solve with the information I provided. The pointer did indeed need to be initialized, but with arguments found in the constructor, which I had not provided here.
I've had to completely rewrite this problem as I've found out a lot more about it now.
Background:
My programme is drawing some 3d objects under directx11. I have a class that contains the data, pointers, and functions needed to draw the required 3d objects. Everything was working well. I could create many different 3d objects and draw them wherever I wanted. Great!
Then I needed to put them in a container and into a vector so I didn't have to create each object manually, this was where the trouble started; it would crash 1 time in 5 or so.
Unhandled exception at 0x00C308C1 in SpritesNTextN3D.exe: 0xC0000005: Access violation reading location 0xFFFFFFFF.
It crashed when using vectors and maps. I continued this line of enquiry and tried using a pointer and new:
ThreeD_Cube* threed_cube_p;
threed_cube_p = new ThreeD_Cube;
This also caused it to crash when I ran its draw function.
threed_cube_p->draw(threeD, camera, d3dContext_mp);
However if created as a standard object:
ThreeD_Cube threed_cube_;
The draw function never crashes.
threed_cube_-.draw(threeD, camera, d3dContext_mp);
Likewise, creating a pointer to threed_cube_ works as expected.
Question:
What is new doing that the default constructor isn't. Is there anything I should be looking at to resolve this problem?
It seems you have a good constructor, but bad/insufficient (default) assignment operator and bad/insufficient (default) copy constructor.
Let's see why some parts of your code works but some not:
//threed_cube_vec[0].draw(threeD, camera, d3dContext_); // doesnt work!!!
It tells you what's in threed_cube_vec[0] is a bad/corrupted object.
ThreeD_Cube test = threed_cube_vec[0]; // But, if I copy it...
In this line, (for some reason) firstly the constructor is called, which gives you a good object. Then the "=" is called, partially the object is modified, but the object is still good since it was already good before the "="
ThreeD_Cube* test = &threed_cube_vec[0];
As for a pointer, it is the essentially object threed_cube_vec[0] itself, so still corrupted.
ThreeD_Cube test = threed_cube_vec[0];
vector<ThreeD_Cube> test2;
test2.push_back(test);
test2[0].draw(threeD, camera, d3dContext_);
This does not fixed the problem as you said. "test" is a good object, but when you push_back(test) into test2, a copy is pushed back [if you change it to test2.push_back(std::move(test) , the problem could be gone]. Since the copy constructor is incomplete, the object in test2[0] is corrupted. Similar scenario happens with your map.
Conclusion: if an object is originated from the constructor, you get a good object; if an object is originated from a copy constructor, it is corrupted.
A quick test you can do: resize your vector after you declare it, the error should be gone temporarily.
Crash after m = XMMatrixIdentity() - aligment memory in classes?
This topic covers the answer to my problem. I eventually tracked it down to XMMATRIX causing crashes with new due to memory alignment.
Here's a shortened version of the problem:
void matrix_test_pointer()
{
XMMATRIX* xmmatrix_p;
xmmatrix_p = new XMMATRIX;
*xmmatrix_p = XMMatrixIdentity(); // this is where it crashes
}
void matrix_test()
{
XMMATRIX xmmatrix;
xmmatrix = XMMatrixIdentity();
}
int main()
{
string wait;
matrix_test();
cout << "matrix_test() completed.\n";
matrix_test_pointer();
cout << "matrix_test_pointer() completed.\n"; // If it does you are lucky :)
cin >> wait;
return 0;
}
Chances are matrix_test will complete but it will crash before pointer will complete.
I'm having problems creating a tmx map from string input.
bool LevelManager::initLevel(int currentLevel)
{
const char* map;
try {
map = LevelManager::getLevel(currentLevel);
} catch (int) {
throw 1;
}
if(map != NULL){
CCLog("%s", map);
tileMap = CCTMXTiledMap::create(map);
tileMap->setAnchorPoint(ccp(0,0));
tileMap->setPosition(ccp(15,20));
this->addChild(tileMap, 5);
backgoundLayer = tileMap->layerNamed("Background");
} else {
throw 1;
}
return true;
}
Thats my code.
It is very unstable. Most of the times it crashes and sometimes it doesn't.
I'm loading my map from the string map. Wich is a const *char.
My map is named Level1.tmx and when i load the map like this: tileMap = CCTMXTiledMap::create("Level1.tmx"); it always works and never crashes.
And i know for a fact that the value of map is Level1.tmx because i log it in the line before the load.
When it crashes the log outputs this: (lldb)
and on the line tileMap->setAnchorPoint(ccp(0,0)); it says "Thread 1: EXC_BAD_ACCESS (code=2, adress=0x0)
Does anyone know why this happens and how to fix it?
Many thanks.
Ps: i'm using xcode, the latest cocos2d-x release and the iPhone simulator
Edit:
Using breakpoints i checked where things go bad while loading the tilemap.
on the line tileMap = CCTMXTiledMap::create(map);
my variable map is still fine
but on line tileMap->setAnchorPoint(ccp(0,0));
it is suddenly corrupted (most of the time)
It sounds like you're returning a char* string created on the stack, which means the memory may or may not be corrupted, depending on circumstances, moon phases, and what not.
So the question is: How is getLevel defined and what does it do (post the code)?
If you do something like this:
const char* LevelManager::getLevel(int level)
{
char* levelName = "default.tmx";
return levelName;
}
…then that's going to be the culprit. The levelName variable is created on the stack, no memory (on the heap) is allocated for it. The levelName variable and the memory it points to become invalid as soon as the method returns.
Hence when the method leaves this area of memory where levelName points to can be allocated by other parts of the program or other method's stack memory. Whatever is in that area of memory may still be the string, or it may be (partially) overridden by other bits and bytes.
PS: Your exception handling code is …. well it shows a lack of understanding what exception handling does, how to use it and especially when. I hope these are just remnants of trying to get to the bottom of the issue, otherwise get rid of it. I recommend reading a tutorial and introductions on C++ exception handling if you want to continue to use exceptions. Especially something like (map != NULL) should be an assertion, not an exception.
I fixed it.
const char* was to blame.
When returning my map as a char * it worked flawless.
const char *levelFileName = level.attribute("file").value();
char *levelChar = new char[strlen(levelFileName) + 1];
std:: strcpy (levelChar, levelFileName);
return levelChar;
Thats how i now return the map.
I'm building a simple generic engine for my true start in the making of games, and I am trying to be somehow organized and decent in the making of my engine, meaning I don't want it to be something I throw to the side once I make what I'm planning to.
I add objects to be displayed, drawObjects, and these can either move, not move, and have an animation, or not have one.
In case they DO have an animation, I want to initialize a single animationSet, and this animationSet will have xxx animationComp inside of it. As I'm trying to be neat and have worked abit on "optimizations" towards memory and cpu usage (such as sharing already-loaded image pointers, and whatever came across my mind), I wanted to not ask for possibly unused memory in arrays.
So I had animationSetS* animationSet = NULL; initially, planning to do a animationSet = animationSetS[spacesINEED]; after, only on the objects that needed animation that I added, being those that aren't animations a NULL and therefore not using memory (correct?).
And then this question popped up! (title)
struct animationComp {
SDL_Rect* clip;
int clipsize;
};
struct animationSetS {
animationComp* animation;
int currentFrame;
int currentAnimation;
int animationNumber;
};
struct drawObject { // Um objecto.
char* name;
SDL_Surface* surface;
bool draw = true;
float xPos;
float yPos;
bool willMove = false; // 0 - Won't move, 10 - Moves alot, TO IMPLEMENT
bool isSprite = false;
animationSetS* animationSet;
};
I dabble alot in my questions, sorry for that. For any clarifications reply here, I'll reply within 10 minutes for the next... 1 hour perhaps? Or more.
Thanks!
Setting the pointer to NULL means that you'll be able to add ASSERT(ptr != NULL); and KNOW that your pointer does not accidentally contain some rubbish value from whatever happens to be in the memory it was using.
So, if for some reason, you end up using the object before it's been properly set up, you can detect it.
It also helps if you sometimes don't use a field, you can still call delete stuff; [assuming it's allocated in the first place].
Note that leaving a variable uninitialized means that it can have ANY value within it's valid range [and for some types, outside the valid range - e.g. pointers and floating point values can be "values that are not allowed by the processor"]. This means that it's impossible to "tell" within the code if it has been initialized or not - but things will go horribly wrong if you don't initialize things!
If this should be really implemented in C++ (as you write), why don't you use the C++ Standard Library? Like
struct animationSetS {
std::vector< std::shared_ptr<animationComp> > animation;
// ...
}