I'm working on a school project using C++ and SFML 2.0, it's due for Tuesday and I've just recently run in to this problem.
I've put an arrow on where the latest Call Stack is.
These are the code parts that I suspect might have something wrong in them. I'm also very new to c++ and I know I do alot of things wrong.
This is in my Background class, it loads all my tiles, sets their position and tiletype and so on.
The GetWayPointList returns a vector of tiles to my EnemyManager class
void Background::Load(QuadTree * quadTree) {
int tempTiles[32][32] = {... Lots of 1's and 0's in here };
for(int i = 0; i < 32; i++)
{
for(int j = 0; j < 32; j++)
{
---> tile[j][i]->tileType = tempTiles[j][i];
tile[j][i]->setPosition(sf::Vector2f((float)(i*32),(float)(j*32)));
if(tile[j][i]->tileType == 1)
{
quadTree->AddObject(tile[j][i]);
}
else if(tile[j][i]->tileType == 0)
{
tile[j][i]->distanceFromStart = INT_MAX;
tile[j][i]->parent = NULL;
vector<Tile*> tempTiles;
if(tile[j+1][i]->tileType == 0)
tempTiles.push_back(tile[j+1][i]);
if(tile[j-1][i]->tileType == 0)
tempTiles.push_back(tile[j-1][i]);
if(tile[j][i+1]->tileType == 0)
tempTiles.push_back(tile[j][i+1]);
if(tile[j][i-1]->tileType == 0)
tempTiles.push_back(tile[j][i-1]);
tile[j][i]->setSuccessors(tempTiles);
tilesList->push_back(tile[j][i]);
}
}
}
}
vector<Tile*>* Background::GetWayPointList()
{
return tilesList;
}
The Call Stack itself says TileShooter v0.1.exe!Background::Load(QuadTree*quadTree) Line 68 + 0x2e bytes.
Line 68 is where the arrow is.
If you need more code / info just say.
Any points on what's possibly wrong would be greatly appriciated.
Best Regards, Fredrik W
Edit
I've edited the code some including tile[j][i] = new Tile();
void Background::Load(QuadTree * quadTree) {
int tempTiles[32][32] = {... Lots of 1's and 0's in here };
for(int i = 0; i < 32; i++)
{
for(int j = 0; j < 32; j++)
{
tile[j][i] = new Tile();
tile[j][i]->tileType = tempTiles[j][i];
tile[j][i]->setPosition(sf::Vector2f((float)(i*32),(float)(j*32)));
if(tile[j][i]->tileType == 1)
{
quadTree->AddObject(tile[j][i]);
}
else if(tile[j][i]->tileType == 0)
{
tile[j][i]->distanceFromStart = INT_MAX;
tile[j][i]->parent = NULL;
vector<Tile*> tempTiles;
----> if(tile[j+1][i]->tileType == 0)
tempTiles.push_back(tile[j+1][i]);
if(tile[j-1][i]->tileType == 0)
tempTiles.push_back(tile[j-1][i]);
if(tile[j][i+1]->tileType == 0)
tempTiles.push_back(tile[j][i+1]);
if(tile[j][i-1]->tileType == 0)
tempTiles.push_back(tile[j][i-1]);
tile[j][i]->setSuccessors(tempTiles);
tilesList->push_back(tile[j][i]);
}
}
}
}
vector<Tile*>* Background::GetWayPointList()
{
return tilesList;
}
That didn't really solve but rather moved the error downwards, I've moved my arrow on where the Call Stack has it's latest call.
So your tile member is defined as Tile* tile[32][32]. That's a 2D array of size 32x32 where each element is a pointer to Tile. However, they are just pointers and currently don't point anywhere in particular - accessing them is undefined behaviour (in your case, an access violation). You need to allocate the actual Tile objects:
for (int i = 0; i < 32; i++) {
for (int j = 0; j < 32; j++) {
tile[i][j] = new Tile();
}
}
Don't forget to do the same kind of loop in the destructor of Background that instead does delete tile[i][j];.
Better yet, don't dynamically allocate your tiles and just define tile as:
Tile tile[32][32];
Even better yet (!), use std::array<std::array<Tile,32>,32>. :)
To answer your edit, even though it's invalidated my above answer: You're accessing the j+1th element of tile. When j is 31, you're accessing tile[32] which is outside the bounds of your array.
Related
currently I'm being asked to design four sorting algorithms (insertion, shell, selection, and bubble) and I have 3 of the 4 working perfectly; the only one that isn't functioning correctly is the Bubble Sort. Now, I'm well aware of how the normal bubble sort works with using a temp var to swap the two indexes, but the tricky part about this is that it needs to use the array index[0] as a temp instead of a normal temp, which is used in swapping, and slide the lower array variables down to the front of the list and at the end of the pass assign the last index to the temp which is the greatest value.
I've been playing around with this for a while and even tried to look up references but sadly I cannot find anything. I'm hoping that someone else has done this prior and can offer some helpful tips. This is sort of a last resort as I've been modifying and running through the passes with pen and paper to try and find my fatal error. Anyways, my code is as follows...
void BubbleSort(int TheArray[], int size)
{
for (int i = 1; i < size + 1; i++)
{
TheArray[0] = TheArray[i];
for (int j = i + 1; j < size; j++)
{
if (TheArray[j] > TheArray[0])
TheArray[0] = TheArray[j];
else
{
TheArray[j - 1] = TheArray[j];
}
}
TheArray[size- 1] = TheArray[0];
}
}
Thanks for any feedback whatsoever; it's much appreciated.
If I understand the problem statement, I think you're looking for something along these lines :
void BubbleSort(int theArray[], int size)
{
for (int i = 1; i < size + 1; i++)
{
theArray[0] = theArray[1];
for (int j = 1; j <= size + 1 - i; j++)
{
if (theArray[j] > theArray[0])
{
theArray[j-1] = theArray[0];
theArray[0] = theArray[j];
}
else
{
theArray[j - 1] = theArray[j];
}
}
theArray[size-i+1] = theArray[0];
}
}
The piece that you're code was missing, I think, was that once you find a new maximum, you have to put it back in the array before placing the new maximum in theArray[0] storage location (see theArray[j-1] = theArray[0] after the compare). Additionally, the inner loop wants to run one less each time since the last element will be the current max value so you don't want to revisit those array elements. (See for(int j = 1 ; j <= size + 1 - i ; j++))
For completeness, here's the main driver I used to (lightly) test this :
int main()
{
int theArray[] = { 0, 5, 7, 3, 2, 8, 4, 6 };
int size = 7;
BubbleSort(theArray, size);
for (int i = 1; i < size + 1; i++)
cout << theArray[i] << endl;
return 0;
}
After spending an entire day debugging, I've noticed that memory leaks always occur when the following function is called:
void merge(TContainer<T> List2)
{
TContainer<T> temp(this->Size);
for (int i = 0; i < this->Size; i++)
{
temp.Interface[i] = this->Interface[i];
}
this->Interface = new T[Size + List2.size()];
Size = Size + List2.size();
for(int i = 0; i < List2.size(); i++)
{
Interface[i] = List2[i];
}
for(int i = List2.size(); i < Size; i++)
{
Interface[i] = temp[i];
};
delete[] temp.Interface;
}
Within the code:
TContainer_Short<unsigned short> Temp = TContainer_Short<unsigned short>(0);
for(int i = (ToUpdate.size() - 1); i >= 0; i--)
{
UpdateInUse = true;
ToUpdate[i].Ad.push_back(AdQueue[i].Indirect[0].Address);
auto Entity = ToUpdate[i];
UpdateInUse = false;
float HighestScore = 0;
int Index = 0;
//Go through all the advertisements on their queue
//Make sure our last index is always the next plot point in our story.
for(int j = 0; j < ToUpdate[i].Ad.size(); j++)
{
AdvertisementBase Ad = *World::get()->getTemplateAd(Entity.Ad[j]);
float temp = returnScore(Entity.Index, Ad);
//If its higher than our current score, set i to this index
if(temp > HighestScore)
Index = j;
}
//Index is last pos when we're currently continuing our plot queue. We haven't changed our mind about what advertisement we want
if(Index !=(Entity.Ad.size() - 1))
{
AdvertisementBase *Ad = World::get()->getTemplateAd(Entity.Ad[Index]);
this->reduceAdChain(Entity.Index, Ad);
}
else
{
//Makes sure that the entity is on track for the next goal that it had already determined
plan(Entity.Index,AdQueue.Interface[Entity.Index].Indirect[0].Address);
}
Temp.push_back(Entity.Index);
ToUpdate.pop_back();
}
if(!ExecutingInUse)
{
ExecutingInUse = true;
Executing.merge(Temp);
ExecutingInUse = false;
}
delete[] Temp.Interface;
}
However, I can't seem to figure out why it only occurs when there are multiple threads. The array itself is only ever being referenced by one thread at a time, (Atomic), so it shouldn't be a problem.
Deleting the Executing::merge reference makes the memory leak go away, and definitely speeds up performance noticeably in single threaded scenarios.
The thing that’s even more odd is that merge is used in other places:
void reduceAdChain(unsigned short Index, TContainer<AdvertisementReference> Ads)
{
AdQueue[Index].Indirect.merge(Ads);
}
And no memory leak gets created, even though reduceAdChain is called almost a full magnitude more often than Executing::merge. And removing merge in this area, creates no noticeable performance increase, even though
A) The arrays being taken in by reduceAdChain for the merge are almost 3x the size on average than the arrays that pass into Executing::merge
and
B) The overall length of reduceAdChain is almost 5x the length of Executing.
However, executing does get cleared at the end of every iteration.
This is one of the weirdest things I've ever ran into in multithreaded environments.
Where Executing gets used:
if(!m_simulated_entities[i]->ExecutingInUse)
{
for (int j = 0; j < m_simulated_entities[i]->Executing.size(); )
{
// Retrieve Tag Data and Update Constants
m_simulated_entities[i]->ExecutingInUse = true;
ExecutingIndex = m_simulated_entities[i]->Executing[j];
m_simulated_entities[i]->ExecutingInUse = false;
TagIndex = m_simulated_entities[i]->TagIndicesPerEntity[ExecutingIndex];
now = std::chrono::system_clock::now();
time_now = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
if (m_simulated_entities[i]->Timing[m_simulated_entities[i]->Executing[j]].TimeConstant == 0)
{
//Make sure all of our new attribute values still allow this entity to live
if(!m_simulated_entities[i]->updateTick(ExecutingIndex))
m_simulated_entities[i]->removeInstance(ExecutingIndex);
else
{
//Compute our new transfer constant
m_simulated_entities[i]->prepare(ExecutingIndex);
//Update the tagging system
m_simulated_entities[i]->updateTags(ExecutingIndex);
//Search for new decisions
m_simulated_entities[i]->ToSearch.push_back(ExecutingIndex);
}
//Remove the index from execution
m_simulated_entities[i]->ExecutingInUse = true;
m_simulated_entities[i]->Executing.Remove(j);
m_simulated_entities[i]->ExecutingInUse = false;
}
else if (time_now - m_simulated_entities[i]->Timing[ExecutingIndex].LastUpdateTime > updateConstants[TagIndex])
{
m_simulated_entities[i]->Timing[ExecutingIndex].TimeConstant--;
m_simulated_entities[i]->Timing[ExecutingIndex].LastUpdateTime = time_now;
j++;
}
}
}
For the test, updateTick is disabled and will always return true, since allowing that function to properly execute would have made finding the memory leak a lot harder.
in the function merge:
this->Interface = new T[Size + List2.size()];
You should check if the pointer this->Interface is NULL or not, if it is not, it should be freed first. Otherwise if the function merge is called multiple times, it will leak.
So the code will be:
if (this->Interface != NULL)
delete[] this->Interface;
this->Interface = new T[Size + List2.size()];
Sorry for possibly stupid question: if you have vectors as "ToUpdate[i].Ad" etc, why don't you use "this->Interface" as vector too? This could save you a lot of time hunting this leak.
So firstly, here's my declaration and initialization:
int** GameField = 0;
GameField = new int*[mapsize];
for(int i = 0; i < mapsize; i++)
GameField[i] = new int[mapsize];
for(int j = 0; j < mapsize; j++)
for(int i = 0; i < mapsize; i++)
GameField[i][j] = 0;
Now i'm trying to insert data with a simple command:
if(!(Player1.find(Move) == Player1.end()) && iter>0)
{
GameResult=1;
}else
{
Player1[Move] = 1;
GameField[Move.first][Move.second]=1;
if(WinCheck(Player1, Move, x, mapsize))
GameResult = 1;
}
Simoultaneously i insert the data into an STL map. Visual Studio has no native display for dynamic data, so i'm unable to view the content of the table. Tried watching memory but it's pretty hard to make sense of it. There is a part of program that seems to be working till a certain point:
bool CheckIfMovePossible(int **GameField, pair <int,int> &Move, int MapSize)
{
int x = Move.first;
int y = Move.second;
bool Neighbour = false;
if(GameField[modulo(x+1,MapSize)][y]==(1||2)) // po prawej
Neighbour = true;
if(GameField[modulo(x+1,MapSize)][modulo(y+1,MapSize)]==(1||2))
Neighbour = true;
if(GameField[modulo(x+1,MapSize)][modulo(y-1,MapSize)]==(1||2))
Neighbour = true;
if(GameField[x][modulo(y+1,MapSize)]==(1||2)) // x
Neighbour = true;
if(GameField[x][modulo(y-1,MapSize)]==(1||2))
Neighbour = true;
if(GameField[modulo(x-1,MapSize)][modulo(y+1,MapSize)]==(1||2)) // po lewej
Neighbour = true;
if(GameField[modulo(x-1,MapSize)][y]==(1||2))
Neighbour = true;
if(GameField[modulo(x-1,MapSize)][modulo(y-1,MapSize)]==(1||2))
Neighbour = true;
return Neighbour;
}
It's supposed to check if there are any neighbouring data in the container. I calculate the values manualy and using the debugger, and in each case the program acts as if there is no data in requested location, while it must there for it is present in the map. Any info will be appreciated.
It appears that what you wanted to do with code like this
if(GameField[modulo(x+1,MapSize)][y]==(1||2))
is this.
if ( GameField[modulo(x+1,MapSize)][y] == 1 ||
GameField[modulo(x+1,MapSize)][y] == 2)
Unrelated to your question, it seems like your logic does a lot of work after it has been determined that the function will return true.
Consider using else if or having the code return true as soon as it's determined that that is the return value.
Your if statements should be like this:
if(GameField[modulo(x+1,MapSize)][y] == 1 ||
GameField[modulo(x+1,MapSize)][y] == 2) // po prawej
Neighbour = true;
You also might want to save your modulo values so as not to have to recalculate them so often.
is there anybody using BWAPI who gets access violation error when accessing the Unit objects of the current game?
i am certain that the error is not in my code.. anyway.. is there anything i can do to avoid access violation?
i am getting this error sometimes at line with the comment bellow.. this code bellow execute many times and only sometimes i get the error..
int Squad::getSize() {
int no = 0;
for (int i = 0; i < (int) agents.size(); i++) {
BaseAgent* agent = agents.at(i);
if (agent != NULL && agent->isAlive() && agent->getUnit() != NULL && !agent->getUnit()->isBeingConstructed()) // this line
no++;
}
return no;
}
this is the code that I use to remove an BaseAgent from the vector.. analyze that and see if i can do it better:
void AgentManager::cleanup() {
//Step 2. Do the cleanup.
int cnt = 0;
int oldSize = (int)agents.size();
for (int i = 0; i < (int)agents.size(); i++) {
if (!agents.at(i)->isAlive()) {
delete agents.at(i);
agents.erase(agents.begin() + i);
cnt++;
i--;
}
}
int newSize = (int)agents.size();
}
the BaseAgent code is on this link
I would speculate that this line:
BaseAgent* agent = agents.at(i);
is returning some invalid pointer which is not set to 0.
Looking at your cleanup code, it looks a bit complicated. I would suggest
looping over the entire vector, deleting the dead elements and
setting the pointers to 0.
After the loop, use the erase-remove idiom to remove all NULL pointers from the vector.
step 1
for (unsigned int i = 0; i < agents.size(); ++i) {
if (!agents.at(i)->isAlive()) {
delete agents.at(i);
agents.at(i) = 0;
}
step 2
agents.erase(std::remove(agents.begin(), agents.end(), 0), agents.end());
I'm having a problem with one of my functions, I'm working on a simple tile map editor, and I'm trying to implement a 3D array to keep track of tiles (x,y, layer). Before this I had a 1D array where all the tiles were just listed sequencially:
bool Map::OnLoad(char* File) {
TileList.clear();
FILE* FileHandle = fopen(File, "r");
if(FileHandle == NULL) {
return false;
}
for(int Y = 0;Y < MAP_HEIGHT;Y++) {
for(int X = 0;X < MAP_WIDTH;X++) {
Tile tempTile;
fscanf(FileHandle, "%d:%d ", &tempTile.TileID, &tempTile.TilePassage);
TileList.push_back(tempTile);
}
fscanf(FileHandle, "\n");
}
fclose(FileHandle);
return true;
}
This basically read strings from the file which looked like:
2:1 1:0 3:2...
Where the first number states the tileID and the second one states the Tile passability. The above function works. My 3D arrays are also correctly constructed, I tested them with simple assignments and calling values out of it. The function that gives me problems is the following (please note that the number 2 i.e. OnLoad2() was added so I can keep the old variables and the function untouched until the prototype is working):
bool Map::OnLoad2(char* File) {
TileList2.clear();
FILE* FileHandle2 = fopen(File, "r");
if(FileHandle2 == NULL) {
return false;
}
for(int Y = 0;Y < MAP_HEIGHT;Y++) {
for(int X = 0;X < MAP_WIDTH;X++) {
Tile tempTile;
fscanf(FileHandle2, "%d:%d ", &tempTile.TileID, &tempTile.TilePassage);
TileList2[X][Y][0] = tempTile;
}
fscanf(FileHandle2, "\n");
}
fclose(FileHandle2);
return true;
}
While this function doesn't trigger the compiler to report any errors, as soon as the application starts, it freezes up and crashes. For additional information MAP_WIDTH and MAP_HEIGHT are set to 40 each and the 3D array was constructed like this:
TileList2.resize(MAP_HEIGHT);
for (int i = 0; i < MAP_HEIGHT; ++i) {
TileList2[i].resize(MAP_WIDTH);
for (int j = 0; j < MAP_WIDTH; ++j)
TileList2[i][j].resize(3);
}
I would appreciate it if you could point me out what do I need to fix, as far as I know I must have messed up the for loop structure, as the 3D array initializes and works properly. Thank you for your help!
TileList2.clear();
This line reinitializes TileList2, so it is back to a zero-length vector. Delete that line, and you will probably be okay.