c++ illegal instruction (core dumped) - c++

So my now completed program works as intended apart from one crash that happens when i keypress 'p' which should only switch an if statement to the else part, however it crashes with the "illegal instruction (core dumped)" message.
#include <stdio.h>
// include the UFCFGL301's standard library
#include <ufcfgl-30-1.h>
// uncomment if you want to use the graphics library
#include <graphics.h>
const uint32 window_Width = 600;
const uint32 window_Height = 400;
using namespace uwe;
struct Rect{
int x,y,width,height,r,g,b;
};
struct Circle{
int x,y,radius,r,g,b;
};
union CircleorRect{
Rect rect;
Circle circle;
};
Rect createRect() {
int x = rand() % window_Width;
int y = rand() % window_Height;
int width = rand() % 200;
int height = rand() % 200;
int r = rand()%256;
int g = rand()%256;
int b = rand()%256;
return Rect{x, y, width, height, r, g, b};
};
Circle createCirc() {
int x = rand() % window_Width;
int y = rand() % window_Height;
int radius = rand() % 200;
int r = rand()%256;
int g = rand()%256;
int b = rand()%256;
return Circle{x, y, radius, r, g, b};
};
Rect createRect();
Circle createCirc();
int main(void) {
// graphics window
initialiseGraphics(window_Width,window_Height);
// variables
int count = 0,pressedcount;
Circle circle[1000];
Rect rects[1000];
bool stopCircs = false;
// creating distinct shapes then mapping them.
loop(
[&](){
rects[count] = createRect();
//if circles = create new circle and paint it
if (stopCircs == false) {
circle[count] = createCirc();
for (size_t i = 0; i < count; i++) {
setColour(circle[i].r,circle[i].g,circle[i].b);
drawFilledCircle(circle[i].x,circle[i].y,circle[i].radius);
}
}
else {
for (size_t i = 0; i < pressedcount; i++) {
setColour(circle[i].r,circle[i].g,circle[i].b);
drawFilledCircle(circle[i].x,circle[i].y,circle[i].radius);
}}
for (size_t i = 0; i < count; i++) {
setColour(rects[i].r,rects[i].g,rects[i].b);
drawFilledRect(rects[i].x,rects[i].y,rects[i].width,rects[i].height);
}
count++;
if (count >= 1000) {
count = 0;
}
},
[&](KeyPress keyPress){
if (getTextCharacter(keyPress) == 'q') {
return true;
}
else if (getTextCharacter(keyPress) == 'p') {
stopCircs = true;
pressedcount = count;
}
else {
return false;
}
});
return 0;
}
The 'p' press should only switch from generating new circles to just loading the older ones, no idea why it causes a crash.
This is the whole thing so if anyone wants to try and run it or tell me how to get a better debugger than trying and failing any help would be appreciated.

In this lambda not all control-paths have a return statement (compiling with a higher error/warning level might diagnose this kind of error).
[&](KeyPress keyPress){
if (getTextCharacter(keyPress) == 'q') {
return true;
}
else if (getTextCharacter(keyPress) == 'p') {
stopCircs = true;
pressedcount = count;
//here maybe missing return
}
else {
return false;
}
// or here maybe missing return
}

Related

Creating an X amount of rectangles which are not intersecting each other on a specified screen size

I managed with some help to know how when two rectangles are intersecting each other, from there it should be easy to make what i just said in the title but ...
So, short story of what i just did below:
Created a for loop from 1 to Number_of_Obstacles
In that for an random obstacle (rectangle/square) is created and it will be checked if it is overlaped with all other obstacles created from 0 to the loop contor (or in other words every obstacle stored in the vector)
Again, the doOverLap function works. Tested it with a square which i made a controller and other random rectangle created on the screen. It outputs in chat when i'm overlaping it and trust me, i overlaped it from all angles.
Here is a picture with the overlaping issue: https://imgur.com/a/ZzorOcD
bool doOverlap(A a, B b)
{
if (a.x1 > b.x2 || b.x1 > a.x2)
return false;
if (a.y1 > b.y2 || b.y1 > a.y2)
return false;
return true;
}
struct Obstacles {
int X, Y;
void Create_Random_Obstacles(Obstacles Obj[], int Numar_Obstacole)
{
srand(time(NULL));
A Rectangle_1;
B Rectangle_2;
/* To avoid rendering outside of the screen */
int X_Axis = X_RESOLUTION - 40;
int Y_Axis = Y_RESOLUTION - 40;
int obstacolX = rand() % X_Axis + 1;
int obstacolY = rand() % Y_Axis + 1;
Obj[0].X = obstacolX;
Obj[0].Y = obstacolY;
for (int i = 1; i < Numar_Obstacole; i++)
{
obstacolX = rand() % X_Axis + 1;
obstacolY = rand() % Y_Axis + 1;
Rectangle_1.x1 = obstacolX;
Rectangle_1.x2 = obstacolX + 40;
Rectangle_1.y1 = obstacolY;
Rectangle_1.y2 = obstacolY + 40;
for (int j = 0; j < i; j++) {
Rectangle_2.x1 = Obj[j].X;
Rectangle_2.x2 = Obj[j].X + 40;
Rectangle_2.y1 = Obj[j].Y;
Rectangle_2.y2 = Obj[j].Y + 40;
if (doOverlap(Rectangle_1, Rectangle_2))
{
std::cout << "Overlap\n";
}
else
{
Obj[i].X = obstacolX;
Obj[i].Y = obstacolY;
}
}
}
}
void Render(SDL_Renderer* renderer, Obstacles Obj[], int Numar_Obstacole) {
for (int i = 0; i < Numar_Obstacole; i++)
{
SDL_Rect r{ Obj[i].X, Obj[i].Y, 40, 40 };
SDL_SetRenderDrawColor(renderer, 255, 160, 15, 255);
SDL_RenderFillRect(renderer, &r);
}
}
};
Restart selection when collision occurs, something like:
bool Has_Overlap(const Obstacles& obj, const Obstacles* Objs, int Size)
{
B Rectangle_2;
Rectangle_2.x1 = obs.X;
Rectangle_2.x2 = obs.X + 40;
Rectangle_2.y1 = obs.Y;
Rectangle_2.y2 = obs.Y + 40;
for (int i = 0; i != Size; ++i) {
A Rectangle_1;
Rectangle_1.x1 = Obs[i].X;
Rectangle_1.x2 = Obs[i].X + 40;
Rectangle_1.y1 = Obs[i].Y;
Rectangle_1.y2 = Obs[i].Y + 40;
if (doOverlap(Rectangle_1, Rectangle_2)) {
return true;
}
}
return false;
}
void Create_Random_Obstacles(Obstacles* Objs, int Size)
{
/* To avoid rendering outside of the screen */
const int X_Axis = X_RESOLUTION - 40;
const int Y_Axis = Y_RESOLUTION - 40;
for (int i = 0; i < Size; i++)
{
do {
Objs[i].X = rand() % X_Axis + 1;
Objs[i].Y = rand() % Y_Axis + 1;
} while (Has_Overlap(Objs[i], Objs, i));
}
}

How can I define a game over in snake game using SFML?

so recently I have been wanting to make a snake game in C++ using SFML in Microsoft Visual studio 2015 and I made one and I am actually pretty satisfied with my work but there is a problem, that I forgot to make a game over for it and it seems like I couldn't make it work and it really had me on edge. So I thought I could use stack overflow's help. I would really appreciate it if you guys would let me know how to make it work and please keep it simple obvious.
Here is my code:
// GraphicalLoopSnakeGame.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <ctime>
#include <SFML/Graphics.hpp>
using namespace sf;
int N = 30, M = 20;
int size = 16;
int w = size * N;
int h = size * M;
int dir, num = 4;
struct Snake {
int x, y;
} s[100];
struct Fruit {
int x, y;
} f;
void Tick() {
for(int i = num; i > 0; --i) {
s[i].x = s[i - 1].x;
s[i].y = s[i - 1].y;
}
if(dir == 0) s[0].y += 1;
if(dir == 1) s[0].x -= 1;
if(dir == 2) s[0].x += 1;
if(dir == 3) s[0].y -= 1;
if((s[0].x == f.x) && (s[0].y == f.y)) {
num++;
f.x = rand() % N;
f.y = rand() % M;
}
if(s[0].x > N) s[0].x = 0;
if(s[0].x < 0) s[0].x = N;
if(s[0].y > M) s[0].y = 0;
if(s[0].y < 0) s[0].y = M;
for(int i = 1; i < num; i++)
if(s[0].x == s[i].x && s[0].y == s[i].y) num = i;
}
int main() {
srand(time(0));
RenderWindow window(VideoMode(w, h), "Snake Game!");
Texture t1, t2, t3;
t1.loadFromFile("images/white.png");
t2.loadFromFile("images/red.png");
t3.loadFromFile("images/green.png");
Sprite sprite1(t1);
Sprite sprite2(t2);
Sprite sprite3(t3);
Clock clock;
float timer = 0, delay = 0.13;
f.x = 10;
f.y = 10;
while(window.isOpen()) {
float time = clock.getElapsedTime().asSeconds();
clock.restart();
timer += time;
Event e;
while(window.pollEvent(e)) {
if(e.type == Event::Closed) window.close();
}
if(Keyboard::isKeyPressed(Keyboard::Left)) dir = 1;
if(Keyboard::isKeyPressed(Keyboard::Right)) dir = 2;
if(Keyboard::isKeyPressed(Keyboard::Up)) dir = 3;
if(Keyboard::isKeyPressed(Keyboard::Down)) dir = 0;
if(Keyboard::isKeyPressed(Keyboard::W)) dir = 3;
if(Keyboard::isKeyPressed(Keyboard::D)) dir = 2;
if(Keyboard::isKeyPressed(Keyboard::A)) dir = 1;
if(Keyboard::isKeyPressed(Keyboard::S)) dir = 0;
if(timer > delay) {
timer = 0;
Tick();
}
////// draw ///////
window.clear();
for(int i = 0; i < N; i++)
for(int j = 0; j < M; j++) {
sprite1.setPosition(i * size, j * size);
window.draw(sprite1);
}
for(int i = 0; i < num; i++) {
sprite2.setPosition(s[i].x * size, s[i].y * size);
window.draw(sprite2);
}
sprite3.setPosition(f.x * size, f.y * size);
window.draw(sprite3);
window.display();
}
return 0;
}
In your Tick() function you can check whether the head bumps into anything after everything has moved in the given direction. If it does, let main() know about it somehow: for example, return a bool which expresses if the game is over. Let's say this bool is called over.
So, add if (over) { window.close(); } inside your while (window.isOpen()) loop (right after calling Tick()) to let main() reach return 0; and finish the program.
EDIT: Think about using std::deque for moving your snake using less code and time: you'd be able to just pop_back() the snake tile farthest from the head and push_front() the new tile where the head currently is (after a tick), simulating crawling one step forwards.
Anyway, after having moved your snake you can check each of its body tiles whether it has the same coordinates as its head. If it does, it means your snake crashed into its tail so the game is over.
// in Tick():
// ...other logic...
tiles.pop_back();
tiles.push_front(new_head_position);
for (/* each tile of your snake except its head */) {
if (tile.x == head.x && tile.y == head.y) {
return false; // game over
}
}
return true; // everything is fine

C++ crash when pushing self-removing back to a vector

I want to genetically recreate a given image
I try to do this in sfml.
I have created a self-parting square that tries to evolve to look
like source image
Sadly, this thing crashes and I have no idea why, I suppose everything is handled nice and the vector appending shouldn't be a problem.
Please check out the code:
The main function:
#include "divisablesquare.h"
#include <SFML/Graphics.hpp>
#include <iostream>
#include <cstring>
#include <string>
#include <error.h>
#include <algorithm>
namespace GLOBAL
{
bool DEBUG_MODE = false;
};
int IDX = 0;
int main(int argc, char * argv[])
{
srand(time(NULL));
std::string def;
for(int i = 1; i < argc; i++)
{
def = argv[i];
std::string def2 = def;
std::transform(def2.begin(), def2.end(), def2.begin(), ::tolower);
if(strcmp(def2.c_str(), "--debug") == 0)
{
GLOBAL::DEBUG_MODE = true;
std::cerr << "Running in debug mode" << std::endl;
}
else
{
break;
}
}
sf::Image sourceImage;
sf::Texture sample;
if(!sourceImage.loadFromFile(def) && GLOBAL::DEBUG_MODE)
{
std::cerr << "Failed to open specified image!" << std::endl;
}
sample.loadFromImage(sourceImage);
sf::RectangleShape sourceRect;
sourceRect.setSize((sf::Vector2f)sourceImage.getSize());
sourceRect.setTexture(&sample);
sf::RenderWindow mainWindow(sf::VideoMode(sourceImage.getSize().x*2+10, sourceImage.getSize().y), "Genetic Image Generator");
std::vector<DivisableSquare> dSquares;
{
DivisableSquare starter(&dSquares, &sourceImage);
starter.init(128, 128, 128, sourceImage.getSize().x, sourceImage.getSize().y, sourceImage.getSize().x + 10, 0);
starter.Shape.setPosition({(float)sourceImage.getSize().x + 10, 0});
starter.Shape.setFillColor({128,128,128});
starter.Shape.setSize({(float)sourceImage.getSize().x, (float)sourceImage.getSize().y});
dSquares.push_back(starter);
}
sf::Clock clock;
while(mainWindow.isOpen())
{
sf::Time elapsed = clock.getElapsedTime();
if(elapsed.asMilliseconds() > 1000)
{
clock.restart();
dSquares.at(rand() % dSquares.size()).Partup();
}
sf::Event mainEvent;
while(mainWindow.pollEvent(mainEvent))
{
if(mainEvent.type == sf::Event::Closed)
mainWindow.close();
}
mainWindow.clear();
mainWindow.draw(sourceRect);
for(auto &&ref: dSquares)
{
mainWindow.draw(ref.Shape);
}
mainWindow.display();
}
}
divisablesquare header:
#ifndef DIVISABLESQUARE_H
#define DIVISABLESQUARE_H
#include <vector>
#include <SFML/Graphics.hpp>
class DivisableSquare
{
private:
sf::Image * parentImage;
std::vector<DivisableSquare> * ParentContainter;
unsigned short red, green, blue;
double width, height;
double posX, posY;
int id;
public:
~DivisableSquare();
sf::RectangleShape Shape;
DivisableSquare(std::vector<DivisableSquare>*, sf::Image*);
void init(unsigned short, unsigned short, unsigned short, unsigned int, unsigned int, unsigned int, unsigned int);
void Partup();
};
#endif // DIVISABLESQUARE_H
and the c++ file:
#include "divisablesquare.h"
#include <random>
#include <algorithm>
#include <iostream>
extern int IDX;
DivisableSquare::DivisableSquare(std::vector<DivisableSquare> *pc, sf::Image*tp)
{
this->ParentContainter = pc;
this->parentImage = tp;
this->id = IDX;
IDX++;
}
DivisableSquare::~DivisableSquare()
{
}
void DivisableSquare::init(unsigned short r, unsigned short g, unsigned short b,
unsigned int width, unsigned int height, unsigned int posX, unsigned int posY)
{
this->red = r;
this->blue = b;
this->green = g;
this->width = width;
this->height = height;
this->posX = posX;
this->posY = posY;
}
void DivisableSquare::Partup()
{
if(this->width < 2 && this->height < 2)
return;
double percentCut = (rand()%60 + 20)/100;
bool horizontalCut = rand()%2;
double posX1, posX2;
double posY1, posY2;
double width1, width2;
double height1, height2;
if(horizontalCut)
{
posX1 = this->posX;
posX2 = (this->posX+this->width)*percentCut;
posY1 = this->posY;
posY2 = this->posY;
width1 = this->width*percentCut;
width2 = this->width*(1-percentCut);
height1 = this->height;
height2 = this->height;
}
else
{
posX1 = this->posX;
posX2 = this->posX;
posY1 = this->posY;
posY2 = (this->posY + this->height)*percentCut;
width1 = this->width;
width2 = this->width;
height1 = this->height*percentCut;
height2 = this->height*(1-percentCut);
}
struct RGB
{
float r, g, b;
float parentCmp;
float originalCmp;
float averageCmp;
/**
* Make sure to append originalCmp later
* also remove "= 0"
* DONE
*/
};
std::vector<RGB> originalPixels1;
std::vector<RGB> originalPixels2;
for(unsigned int i = posX1; i < posX1+width1; i++)
{
for(unsigned int j = posY1; j < posY1+height1; j++)
{
if(this->parentImage->getSize().x > i && this->parentImage->getSize().y > j)
{
RGB pixel;
pixel.r = this->parentImage->getPixel(i, j).r;
pixel.g = this->parentImage->getPixel(i, j).g;
pixel.b = this->parentImage->getPixel(i, j).b;
originalPixels1.push_back(pixel);
}
}
}
for(unsigned int i = posX2; i < posX2+width2; i++)
{
for(unsigned int j = posY2; j < posY2+height2; j++)
{
if(this->parentImage->getSize().x > i && this->parentImage->getSize().y > j)
{
RGB pixel;
pixel.r = this->parentImage->getPixel(i, j).r;
pixel.g = this->parentImage->getPixel(i, j).g;
pixel.b = this->parentImage->getPixel(i, j).b;
originalPixels2.push_back(pixel);
}
}
}
RGB pix1 = {0,0,0,0,0,0}, pix2={0,0,0,0,0,0};
for(auto &&ref : originalPixels1)
{
pix1.r += ref.r;
pix1.g += ref.g;
pix1.b += ref.b;
}
pix1.r /= originalPixels1.size();
pix1.g /= originalPixels1.size();
pix1.b /= originalPixels1.size();
for(auto &&ref : originalPixels2)
{
pix2.r += ref.r;
pix2.g += ref.g;
pix2.b += ref.b;
}
pix2.r /= originalPixels1.size();
pix2.g /= originalPixels1.size();
pix2.b /= originalPixels1.size();
auto comparVal = [](RGB v1, RGB v2)
{
float val1 = 0.2126*v1.r + 0.7152*v1.g + 0.0722*v1.b;
float val2 = 0.2126*v2.r + 0.7152*v2.g + 0.0722*v2.b;
return (val1 > val2) ? val1-val2 : val2-val1;
};//smaller - better
RGB first[100];
RGB second[100];
for(int i = 0; i < 100; i++)
{
first[i].r = rand() % 255;
first[i].g = rand() % 255;
first[i].b = rand() % 255;
second[i].r = rand() % 255;
second[i].g = rand() % 255;
second[i].b = rand() % 255;
}
// insert orginalcmp here
for(int i = 0; i < 100; i++)
{
first[i].originalCmp = comparVal(first[i], pix1);
second[i].originalCmp = comparVal(second[i], pix2);
}
RGB pRgb;
pRgb.r = this->red;
pRgb.b = this->blue;
pRgb.b = this->blue;
for(int i = 0; i < 100; i++)
{
first[i].parentCmp = comparVal(first[i], pRgb);
second[i].parentCmp = comparVal(second[i], pRgb);
first[i].averageCmp = (first[i].originalCmp+first[i].parentCmp)/2;
second[i].averageCmp = (second[i].originalCmp+second[i].parentCmp)/2;
}
std::sort(first, first+100, [](const RGB& l, const RGB& r){return r.averageCmp > l.averageCmp;});
std::sort(second, second+100, [](const RGB& l, const RGB& r){return r.averageCmp > l.averageCmp;});
RGB bestfirst = first[rand()%10], bestsecond = second[rand()%10];
DivisableSquare firstSQ(this->ParentContainter, this->parentImage);
DivisableSquare secondSQ(this->ParentContainter, this->parentImage);
firstSQ.init(bestfirst.r, bestfirst.g, bestfirst.b, width1, height1, posX1, posY1);
secondSQ.init(bestsecond.r, bestsecond.g, bestsecond.b, width2, height2, posX2, posY2);
firstSQ.Shape.setFillColor({(sf::Uint8)bestfirst.r, (sf::Uint8)bestfirst.g, (sf::Uint8)bestfirst.b});
secondSQ.Shape.setFillColor({(sf::Uint8)bestsecond.r, (sf::Uint8)bestsecond.g, (sf::Uint8)bestsecond.b});
firstSQ.Shape.setSize({(float)width1, (float)height1});
secondSQ.Shape.setSize({(float)width2, (float)height2});
firstSQ.Shape.setPosition({(float)posX1 + this->parentImage->getSize().x + 10, (float)posY1});
secondSQ.Shape.setPosition({(float)posX2 + this->parentImage->getSize().x + 10, (float)posY2});
this->ParentContainter->push_back(firstSQ);
this->ParentContainter->push_back(secondSQ);
//crash here
for(unsigned int i = 0; i < this->ParentContainter->size(); i++)
{
if(this->ParentContainter->at(i).id == this->id)
this->ParentContainter->erase(this->ParentContainter->begin()+i);
}
}
I know this is a poor code but i just wanted to test things out, what could cause a vector::push_back to crash my app?
The problem is that you're adding to dSquares while executing code using a member of the vector. When the vector is resized (during the this->ParentContainter->push_back(firstSQ); call), the object that this points to is moved (since it is part of the vector). However, this keeps pointing at the previous location of the object, and when you try to push the second new square you access this deallocated memory, resulting in Undefined Behavior and (in this case) a crash.
A possible fix is to call dSquares.reserve(dSquares.size() + 2); before you call dSquares.at(rand() % dSquares.size()).Partup();. This will allocate extra memory of the (potential) two new objects that are added so that when you call push_back within Partup a reallocation of the vector will not occur.
Another possibility is to erase the parent square first, then push the two new squares to the vector. When you push the first new square, it won't have to resize the vector (since there will be space for at least one element from removing the parent). Pushing the second element might result in a resize, so dereferencing this after that push could still crash.

Debugging a bad_alloc error c++

When I run my code everything seems to be working fine but after a certain number of timesteps (usually ~100, but a different number each time) I get the error:
"terminate called after throwing an instance of 'std::bad_alloc' "
Not really sure how to go about debugging this as it doesn't happen at the same point each time the code runs. I will post my code but it's quite long and is admittedly a bit of a mess (this is my first real attempt at writing a program in c++), but I will try and explain the structure and where I would expect the most likely place for the origin of the error to be.
The basic structure is that I have an array of "birds" (a class I define) that choose how to update themselves at every time step by some quite complicated calculation. In doing so it regularly calls the function getVisualState to update a linked list that every bird stores as its "visual state". I believe this is the only time I allocate any memory dynamically during the simulation, so I guess there's a pretty good chance this is the source of the error. The function Bird::resetVisualState() should clear the allocated memory after it's been used (but it doesn't seem like I am running out of memory, at least monitoring it in the task manager).
If anyone can see anything they think may be the source of the problem that would be fantastic, or if not just any suggestions for how I should actually debug this!
#include <iostream>
#include <cmath>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include <ctime>
#include <vector>
#include <algorithm>
#include <fstream>
#include "birdClasses.h"
using namespace std;
/*
nBirds, nSteps, nF, v, dt, birdRad defined in "birdClasses.h"
*/
//define other parameters.
const int nSensors = 20;
const int nMoves = 3; //no. possible moves at each step.
double dTheta = 15*M_PI/180.0; //angle that birds can change their orientation by in a timestep.
double moves[nMoves] = {-dTheta, 0, dTheta}; //possible moves.
double noise = 0.0;
double initBoxX = 20, initBoxY = 20; //size of initial box particles are placed in.
double sensorFrac[nSensors];
double sensorRef[nSensors];
double sensorRange = 2*M_PI/((double)nSensors);
int counter = 0;
int nps = numStates(nMoves,nF);
int *possibleStates = new int[nps];
//variables to record positions and orientations.
double xPositions[nSteps][nBirds], yPositions[nSteps][nBirds], orientations[nSteps][nBirds];
//array to keep track of which collisions are possible.
int couldCollide[nF][nBirds][nBirds];
//function prototypes
bool checkCollision(int i, int nFut, Bird *birds, double xi, double yi);
unsigned long int getVisualState(Bird *birdList, int nFut, int i, double cX, double cY, double cAng);
void updateTree(double exploreX, double exploreY, double exploreO, Bird *bird, int bn, int nFut);
int main()
{
sensorRef[0] = sensorRange;
for(int u=1; u<nSensors; u++) sensorRef[u] = sensorRef[u-1] + sensorRange;
//set up GSL random number generator.
const gsl_rng_type * Tr;
gsl_rng * RNG;
gsl_rng_env_setup();
Tr = gsl_rng_default;
RNG = gsl_rng_alloc (Tr);
gsl_rng_set(RNG,time(NULL));
//set up output
ofstream output("output.txt");
//initialize birds in a box randomly, all with the same orientation.
Bird birdList[nBirds];
for(int i=0; i<nBirds; i++) {
birdList[i].set_position(gsl_ran_flat(RNG,0,initBoxX),gsl_ran_flat(RNG,0,initBoxY));
}
//ACTUAL CODE
int uniqueVisStates[nMoves];
double cX, cY, fX, fY, exploreX, exploreY, exploreO;
//main time step loop
for(int ts=0; ts<nSteps; ts++) {
//save current positions
for(int i=0; i<nBirds; i++) {
xPositions[ts][i] = birdList[i].get_xPos();
yPositions[ts][i] = birdList[i].get_yPos();
orientations[ts][i] = birdList[i].get_orientation();
birdList[i].updateFuture();
}
//update list of possible collisions.
for(int nFut=0; nFut<nF; nFut++) {
for(int i=0; i<nBirds; i++) {
cX = birdList[i].get_xPos(); cY = birdList[i].get_yPos();
counter = 0;
for(int j=0; j<nBirds; j++) {
if(i==j) {
continue;
} else {
fX = birdList[j].get_futureX(nFut); fY = birdList[j].get_futureY(nFut);
if((cX-fX)*(cX-fX)+(cY-fY)*(cY-fY) < ((nFut+1)*v*dt+2*birdRad)*((nFut+1)*v*dt+2*birdRad)) {
couldCollide[nFut][i][counter]=j;
counter++;
}
}
}
if(counter < nBirds) couldCollide[nFut][i][counter]=-1;
}
}
//loop over birds to choose how they update their orientation.
for(int bn=0; bn<nBirds; bn++) {
//loop over possible moves bird can make NOW.
for(int l=0; l<nMoves; l++) {
uniqueVisStates[l]=0;
}
for(int mn=0; mn<nMoves; mn++) {
for(int l=0; l<nps; l++) {
possibleStates[l]=0;
}
counter = 0;
exploreO = birdList[bn].get_orientation() + moves[mn];
exploreX = birdList[bn].get_xPos() + cos(exploreO)*v*dt;
exploreY = birdList[bn].get_yPos() + sin(exploreO)*v*dt;
updateTree(exploreX,exploreY,exploreO,&birdList[0],bn,0);
vector<int> visStates (possibleStates,possibleStates+counter);
vector<int>::iterator it;
sort (visStates.begin(),visStates.end());
it = unique(visStates.begin(),visStates.end());
uniqueVisStates[mn] = distance(visStates.begin(),it);
}
int maxInd = 0, maxVal = uniqueVisStates[0];
for(int h=1; h<nMoves; h++) {
if(uniqueVisStates[h] > maxVal) {
maxInd = h; maxVal = uniqueVisStates[h];
} else if(uniqueVisStates[h]==maxVal) {
if(abs(moves[h])<abs(moves[maxInd])) {
maxInd = h;
}
}
}
birdList[bn].update_Orientation(moves[maxInd]);
birdList[bn].update_Pos(birdList[bn].get_xPos()+cos(birdList[bn].get_orientation())*v*dt,birdList[bn].get_yPos()+sin(birdList[bn].get_orientation())*v*dt);
}
for(int bn=0; bn<nBirds; bn++) birdList[bn].finishUpdate();
cout << ts << "\n";
}
//OUTPUT DATA INTO A TEXT FILE.
for(int ts=0; ts<(nSteps-1); ts++) {
for(int bn=0; bn<nBirds; bn++) {
output << xPositions[ts][bn] << " " << yPositions[ts][bn] << " " << orientations[ts][bn] << "\n";
}
}
delete[] possibleStates;
return 0;
}
bool checkCollision(int i, int nFut, Bird *birds, double xi, double yi) {
int cond = 1; int index, counti=0;
while(cond) {
index = couldCollide[nFut][i][counti];
if(index==-1) break;
double xj = birds[index].get_futureX(nFut);
double yj = birds[index].get_futureY(nFut);
if((xi-xj)*(xi-xj)+(yi-yj)*(yi-yj) < 4*birdRad*birdRad) {
return 1;
}
counti++;
if(counti==nBirds) break;
}
return 0;
}
unsigned long int getVisualState(Bird *birdList, int nFut, int i, double cX, double cY, double cAng) {
//finds the visual state of bird i based on its current "exploring position" and the predicted positions of other birds at timestep nFut.
//visual state is defined by discretizing the bird's field of view into nSensors (relative to current orientation) and creating a vector of
//0s and 1s depending on whether each sensor is < half covered or not. This is then converted to an integer (as we are actually interested only
//in the number of unique visual states.
double relX, relY, relDist, dAng, s, dTheta, ang1, ang2;
//clear current visual state.
birdList[i].resetVisualState();
for(int j=0; j<nBirds; j++) {
if(i==j) continue;
relX = birdList[j].get_futureX(nFut)-cX;
relY = birdList[j].get_futureY(nFut)-cY;
relDist = sqrt(relX*relX+relY*relY);
dAng = acos((cos(cAng)*relX+sin(cAng)*relY)/relDist);
dTheta = atan(birdRad/relDist);
s = cos(cAng)*relY - sin(cAng)*relX;
if( s<0 ) dAng = 2*M_PI-dAng;
ang1 = dAng - dTheta; ang2 = dAng + dTheta;
if( ang1 < 0 ) {
birdList[i].addInterval(0,ang2);
birdList[i].addInterval(2*M_PI+ang1,2*M_PI);
} else if( ang2 > 2*M_PI ) {
birdList[i].addInterval(0,fmod(ang2,2*M_PI));
birdList[i].addInterval(ang1,2*M_PI);
} else {
birdList[i].addInterval(ang1,ang2);
}
}
Node *sI = birdList[i].get_visualState();
birdList[i].cleanUp(sI);
int ind1, ind2;
for(int k=0; k<nSensors; k++) sensorFrac[k]=0.0; //initialize.
while(sI->next->next != 0) {
ang1 = sI->value; ang2 = sI->next->value;
ind1 = floor(ang1/sensorRange); ind2 = floor(ang2/sensorRange);
if(ind2==nSensors) ind2--; //this happens if ang2 = 2pi (which can happen a lot).
if(ind1==ind2) {
sensorFrac[ind1] += (ang2-ang1)/sensorRange;
} else if(ind2-ind1==1) {
sensorFrac[ind1] += (sensorRef[ind1]-ang1)/sensorRange;
sensorFrac[ind2] += (ang2-sensorRef[ind1])/sensorRange;
} else {
sensorFrac[ind1] += (sensorRef[ind1]-ang1)/sensorRange;
sensorFrac[ind2] += (ang2-sensorRef[ind2-1])/sensorRange;
for(int y=ind1+1;y<ind2;y++) sensorFrac[y] = 1.0;
}
sI=sI->next->next;
}
//do final interval separately.
ang1 = sI->value; ang2 = sI->next->value;
ind1 = floor(ang1/sensorRange); ind2 = floor(ang2/sensorRange);
if(ind2==nSensors) ind2--; //this happens if ang2 = 2pi (which can happen a lot).
if(ind1==ind2) {
sensorFrac[ind1] += (ang2-ang1)/sensorRange;
} else if(ind2-ind1==1) {
sensorFrac[ind1] += (sensorRef[ind1]-ang1)/sensorRange;
sensorFrac[ind2] += (ang2-sensorRef[ind1])/sensorRange;
} else {
sensorFrac[ind1] += (sensorRef[ind1]-ang1)/sensorRange;
sensorFrac[ind2] += (ang2-sensorRef[ind2-1])/sensorRange;
for(int y=ind1+1;y<ind2;y++) sensorFrac[y] = 1.0;
}
int output = 0, multiplier = 1;
for(int y=0; y<nSensors; y++) {
if(sensorFrac[y]>0.5) output += multiplier;
multiplier *= 2;
}
return output;
}
void updateTree(double exploreX, double exploreY, double exploreO, Bird *bird, int bn, int nFut) {
double o,x,y;
if(checkCollision(bn,nFut,bird,exploreX,exploreY)) return;
int vs = getVisualState(bird,nFut,bn,exploreX,exploreY,exploreO);
possibleStates[counter] = vs;
counter++;
if(nFut < (nF-1)) {
for(int m=0; m<nMoves; m++) {
o = exploreO + moves[m];
x = exploreX + cos(o)*v*dt;
y = exploreY + sin(o)*v*dt;
updateTree(x,y,o,bird,bn,nFut+1);
}
} else {
return;
}
}
"birdClasses.h":
#ifndef BIRDCLASSES_H_INCLUDED
#define BIRDCLASSES_H_INCLUDED
#include <iostream>
#include <cmath>
using namespace std;
//DEFINE SOME GLOBAL PARAMETERS OF THE SIMULATION
const int nBirds = 50;
const int nF = 6; //number of future timesteps to consider.
const int nSteps = 200;
const double v = 20, dt = 0.1, birdRad = 0.2;
int numStates(int numMoves, int nFut) {
int num = 1; int multiplier = numMoves;
for(int i=1; i<nFut; i++) {
num += multiplier;
multiplier *= numMoves;
}
return num;
}
//Node class is just for a linked list (used in constructing the visual states),
class Node {
public:
int identifier; // 0 is left side of interval, 1 is right side
double value; //angular value.
Node *next; //pointer to the next interval.
void display(Node *start);
};
//printout linked list if necessary (mainly for debugging purposes).
void Node::display(Node *start) {
if(start != 0) {
double inter = start->value;
cout << inter << " ";
display(start->next);
}
}
//bird class.
class Bird {
double currX, currY;
double updatedX, updatedY;
double currOrientation;
double futureX[nF], futureY[nF];
Node *visualState;
public:
Bird() {
currOrientation=0.0; currX = 0.0; currY = 0.0;
visualState = new Node;
visualState->value = 0.0;
visualState->next = new Node;
visualState->next->value = 0.0;
visualState->next->next = 0;
}
Bird(double x, double y, double o) {
currX = x; currY = y; currOrientation = o;
visualState = new Node;
visualState->value = 0.0;
visualState->next = new Node;
visualState->next->value = 0.0;
visualState->next->next = 0;
}
void set_position(double x, double y) {
currX = x; currY = y;
}
double get_xPos() {
return currX;
}
double get_yPos() {
return currY;
}
double get_orientation() {
return currOrientation;
}
double get_futureX(int ts) {
return futureX[ts];
}
double get_futureY(int ts) {
return futureY[ts];
}
//return pointer to first node.
Node* get_visualState() {
return visualState;
}
void updateFuture() {
//use current orientation and position to update future positions.
for(int i=0; i<nF; i++) {
futureX[i] = currX + v*(i+1)*cos(currOrientation)*dt;
futureY[i] = currY + v*(i+1)*sin(currOrientation)*dt;
}
}
void update_Pos(double x, double y) {
updatedX = x;
updatedY = y;
}
//run this after all birds have updated positions:
void finishUpdate() {
currX = updatedX;
currY = updatedY;
}
void update_Orientation(double o) {
currOrientation += o;
}
//add the interval defined by [l r] to the visual state.
void addInterval(double l, double r) {
int placed = 0; double cL = 0.0; double cR = 0.0;
if(visualState->value==0.0 && visualState->next->value==0.0) { //then this is first interval to place.
visualState->value = l;
visualState->next->value = r;
placed = 1;
return;
}
Node *curr_L = visualState;
Node *prev_L = visualState;
while(placed==0) {
cL = curr_L->value;
cR = curr_L->next->value;
if(l<cL && r<cL) { //add new interval before this one.
Node *newRoot = new Node;
newRoot->value = l;
newRoot->identifier = 0;
newRoot->next = new Node;
newRoot->next->value = r;
newRoot->next->next = curr_L;
if(curr_L == visualState) {
visualState = newRoot;
} else {
prev_L->next->next = newRoot;
}
placed = 1;
} else if(l <= cL && r >= cR) {
curr_L->value = l;
curr_L->next->value = r;
placed = 1;
} else if(l <= cL && r <= cR) {
curr_L->value = l;
placed = 1;
} else if(l >= cL && r <= cR) {
placed = 1; //dont need to do anything.
} else if(l >= cL && l<=cR && r >= cR) {
curr_L->next->value = r;
placed = 1;
}
if(l > cR && r > cR) {
if(curr_L->next->next != 0) {
prev_L = curr_L;
curr_L = curr_L->next->next;
} else {
Node *newEndL = new Node;
newEndL->value = l;
newEndL->identifier = 0;
newEndL->next = new Node;
newEndL->next->value = r;
newEndL->next->identifier = 1;
newEndL->next->next = 0;
curr_L->next->next = newEndL;
placed = 1;
}
}
}
}
//remove any overlaps.
void cleanUp(Node *start) {
Node *NP, *NNP; NP = start->next->next;
if(NP==0) return;
NNP = start->next->next->next->next;
double cL = start->value, cR = start->next->value, nL = start->next->next->value, nR = start->next->next->next->value;
if(nL < cR) {
if(nR > cR) {
start->next->value = nR;
}
start->next->next = NNP;
}
if(NNP!=0) cleanUp(NP);
}
//reset the visual state.
void resetVisualState() {
Node *cNode = visualState;
Node *nNode = visualState->next;
while(nNode != 0) {
delete cNode;
cNode = nNode;
nNode = nNode->next;
}
delete cNode;
delete nNode;
visualState = new Node;
visualState->identifier = 0;
visualState->value = 0.0;
visualState->next = new Node;
visualState->next->identifier = 1;
visualState->next->value = 0.0;
visualState->next->next = 0;
return;
}
};
#endif // BIRDCLASSES_H_INCLUDED
or if not just any suggestions for how I should actually debug this!
You can try to set catchpoint in gdb to catch std::bad_alloc exception:
(gdb) catch throw bad_alloc
(See Setting Catchpoints)
If you are able to reproduce this bad_alloc in gdb you can then look at bt to see possible reason of this exception.
I think this is a logic bug and not necessarily memory related.
In void addInterval(double l, double r) you declare
Node *curr_L = visualState;
Node *prev_L = visualState;
These pointers will now point to whatever the member visualState is pointing to.
later on you are changing visualState to point to a newly created Node
Node *newRoot = new Node;
// ....
if(curr_L == visualState) {
visualState = newRoot;
but your pointers curr_L and prev_L will still point to whatever visualState was pointing to before. The only time you change those pointers is at
if(curr_L->next->next != 0) {
prev_L = curr_L;
curr_L = curr_L->next->next;
which is the same as
if(WHATEVER_VISUAL_STATE_USED_TO_POINT_TO->next->next != 0) {
prev_L = curr_L;
curr_L = curr_L->next->next;
Is this your intention? You can follow the assignment of curr_L by looking for *curr_L = * in your editor.
I would suggest testing your code on a small data sample and make sure your code follows your intentions. Use a debugger or trace outputs. Use
valgrind if you have access to it, I think you will appreciate valgrind.

Memory leak while using SDL2 Texture

I am in the progress of making a game which uses SDL_TTF and SDL_Image. I have one function called browseinventory which allows you to check out the stats of an item once you hover over it. That's where the memory leak occurs. Baically once you've hovered over an item slot the program check if there's anything in said slot and if there is, Text class objects are set with the item's parameters and then rendered.
I am pretty sure that the fault lies within the Text class, as memory usage rapidly increases once I've hovered over an item.
Text class:
class Text
{
public:
Text() {w = 0; h = 0; saying = ""; Textthing = NULL;}
~Text(){destroy();}
void destroy(){SDL_DestroyTexture(Textthing); Textthing = 0; saying = "", w = 0, h = 0;}
void render(int, int, int, SDL_Renderer*);
void settext(string, SDL_Color);
void rendertest(int, int, SDL_Renderer*);
int rows;
private:
string saying;
SDL_Texture *Textthing;
int w, h;
unsigned int flag1 = 0, flag2, loops = 0;
string saying1;
unsigned int counter;
bool spaceflag = 0;
};
render():
void Text::render(int x, int y, int maxchars = 100, SDL_Renderer *Temp = Saviour)
{
rows = 0;
flag1 = 0, flag2 = maxchars, loops = 0;
int increment = maxchars;
if (resolution == "800x600")
{
flag2 = maxchars*0.8;
increment = maxchars*0.8;
}
spaceflag = 0;
do
{
spaceflag = 0;
for (counter = flag1; counter < flag2 && counter < saying.length(); counter++)
{
if (counter > flag2-10 && saying[counter] == ' ')
{
spaceflag = 1;
break;
}
saying1 += saying[counter];
}
asdfgfa1.settext(saying1);
asdfgfa1.rendertest(x, y + loops*(SCREEN_HEIGHT/19), Temp);
saying1 = "";
loops++;
rows++;
if (flag2 > saying.length())
break;
if (spaceflag == 0)
{
flag1 = flag2;
flag2 += increment;
}
else
{
flag1 = counter;
flag2 = counter + increment;
}
}while (1);
asdfgfa1.destroy();
SDL_DestroyTexture(Textthing);
Textthing = 0;
}
setText():
void Text::settext(string stuff, SDL_Color Colour = {255, 255, 255})
{
saying = stuff;
SDL_Surface *Surf = TTF_RenderText_Solid(Arial, stuff.c_str(), Colour);
w = Surf->w;
h = Surf->h;
Textthing = SDL_CreateTextureFromSurface(Saviour, Surf);
SDL_FreeSurface(Surf);
Surf = 0;
}