C++ const array change without reason - c++

I have a problem with a piece of code. I'll provide you a simplified version :
class AdvancedImage
{
Image *_source;
int _w;
int _h;
AdvancedImage(const Image *src, const PointFloat corners[], int w, int h)
{
InitializeInstanceFields();
_source = new Image(src->data, src->h, src->w);
_w = w;
_h = h;
PointFloat newPoints[4];
for (int i = 0; i < 4; i++)
{
newPoints[i] = corners[i];
}
/* Initialisation continue... */
}
InitializeInstanceFields()
{
_w = 0;
_h = 0;
}
}
class Image
{
unsigned char *data;
int width;
int height;
int size;
Image(const unsigned char newData[], int h, int w)
{
InitializeInstanceFields();
this->height = h;
this->width = w;
this->size = h * w;
this->data = new unsigned char[this->size];
for (int i = 0; i < this->size; i++)
{
this->data[i] = newData[i];
}
}
}
class PointFloat
{
float X;
float Y;
PointFloat(float x, float y)
{
this->X = x;
this->Y = y;
}
}
And I'm using the AdvancedImage like this :
void myFunction (const Image *img, const PointFloat corners[])
{
AdvancedImage *advImg = 0;
/* Some code */
advImg = new AdvancedImage(img, corners, 15, 30);
/* Code continue */
}
My problem is that the values in corners change after doing the new AdvancedImage. I try to debug, and I saw something I can't explain. In constructor AdvancedImage, corners[0] is {76.0, 45.0}. I added a watch to &corners, in constructor new Image values don't change, but when code return from constructor (goes to line _w = w;) values are now something like {7.7877970e40, 0.2554460e-20}.
I've looked for a solution but nothing do. How can I solve this problem ? Where can it come from ?

Related

Strange C ++ behavior when i using a template in which need to calculate the address of an array cell

I created a matrix class and for example a simple cleanup function
template<typename T>
class matrix
{
public:
matrix(int Lenght, int Height)
{
this->container = new T[this->lenght * this->height];
this->lenght = Lenght;
this->height = Height;
}
void Nulling()
{
size_t A = sizeof(T);
for (int i = 0; i < (this->height * this->lenght); i++)
{
this->container)[i] = 0;
//((T*)this->container)[i] = 0; // same result
}
}
T* container = nullptr;
int lenght;
int height;
};
when i == 100226, debugging stops and an error occurs while writing ( i have 512*512 matrix so its 262144 elements)
I think problem is incorrect calculating adress with templates, i try this construction
size_t A = sizeof(T);
for (int i = 0; i < (this->height * this->lenght); i++)
{
this->container[0] = 0;
this->container += A;
}
its cause error on i == 12529
So i dont know what to do now.
In your constructor, the statement
this->container = new T[this->lenght * this->height];
Has undefined behavior, because you are using this->lenght and this->height before they have been assigned values, thus the size of the allocated array is indeterminate. You need to do those assignments first:
matrix(int Lenght, int Height)
{
this->lenght = Lenght;
this->height = Height;
this->container = new T[this->lenght * this->height];
}
Alternatively, use the input values instead of the class members when allocating the array:
matrix(int Lenght, int Height)
{
this->container = new T[Lenght * Height];
this->lenght = Lenght;
this->height = Height;
}

Dynamically create a Three-Dimensional array OR a Two-Dimensional Array in C++

I'm currently trying to make a program that will generate a maze to be exported to a game. This program will take user input to set some properties of the maze. I want one of the options to be if the maze will have only two dimensions (a single floor), or three (two or more floors). To achieve that, I'm dynamically allocating an array int the Maze class like so:
In Maze.hpp:
class Maze {
private:
unsigned int width_, length_, height_;
Cell*** matrix = nullptr;
};
In Maze.cpp:
Maze::Maze() { // Default constructor
width_ = 20;
length_ = 20;
height_ = 0;
matrix = new Cell**[width_];
for (unsigned int x {}; x < width_; ++x) {
matrix[x] = new Cell*[length_];
for (unsigned int y {}; y < length_; ++y) {
matrix[x][y] = new Cell(x, y);
}
}
}
Maze::Maze(int width, int length) { // 2D maze constructor
width_ = width;
length_ = length;
height_ = 0;
matrix = new Cell**[width_];
for (unsigned int x {}; x < width_; ++x) {
matrix[x] = new Cell*[length_];
for (unsigned int y {}; y < length_; ++y) {
matrix[x][y] = new Cell(x, y);
}
}
}
Maze::Maze(int width, int length, int height) { // 3D maze constructor
width_ = width;
length_ = length;
height_ = height;
matrix = new Cell**[width_];
for (unsigned int x {}; x < width_; ++x) {
matrix[x] = new Cell*[length_];
for (unsigned int y {}; y < length_; ++y) {
matrix[x][y] = new Cell[height];
for (unsigned int z {}; z < height_; ++z) {
matrix[x][y][z] = Cell(x, y, z);
}
}
}
}
But as you can see, if I use two dimensions, I end up with a pointer for every individual cell in the maze, meanwhile, with three dimensions I end up with a cell object. I would prefer if in both cases I could have a cell object, but I don't know how to achieve that.
Is there a way to do this? Or is this the only option I have?
As asked, here is the declaration of Cell:
Cell.hpp:
class Cell {
private:
unsigned int xPos_, yPos_, zPos_;
public:
Cell(unsigned int xPos, unsigned int yPos);
Cell(unsigned int xPos, unsigned int yPos, unsigned int zPos);
Cell();
};
Cell.cpp:
Cell::Cell(unsigned int xPos, unsigned int yPos) {
xPos_ = xPos;
yPos_ = yPos;
}
Cell::Cell(unsigned int xPos, unsigned int yPos, unsigned int zPos) {
xPos_ = xPos;
yPos_ = yPos;
zPos_ = zPos;
}
As suggested in the comments of the question, I'll change to std::vector instead of using triple pointers.
Also, as a 2D array is simply a 3D array with only one value in the third dimension, I will just change the code to that. (This was also suggested in the comments)
I'll update this answer with the new code when I'm done with it.
UPDATE:
Here's what the final code looks like:
Cell.hpp:
class Cell {
private:
unsigned xPos_, yPos_, zPos_;
public:
Cell(unsigned xPos, unsigned yPos, unsigned zPos);
Cell();
};
Cell.cpp:
Cell::Cell(unsigned xPos, unsigned yPos, unsigned zPos) {
xPos_ = xPos;
yPos_ = yPos;
zPos_ = zPos;
}
Maze.hpp:
class Maze {
private:
unsigned width_, length_, height_;
std::vector<std::vector<std::vector<Cell>>> matrix;
void generateMatrix();
public:
Maze();
Maze(unsigned width, unsigned length);
Maze(unsigned width, unsigned length, unsigned height);
};
Maze.cpp:
Maze::Maze() { // Default constructor
width_ = 20;
length_ = 20;
height_ = 1;
Maze::generateMatrix();
}
Maze::Maze(unsigned width, unsigned length) { // 2D maze constructor
width_ = width;
length_ = length;
height_ = 1;
Maze::generateMatrix();
}
Maze::Maze(unsigned width, unsigned length, unsigned height) { // 3D maze constructor
width_ = width;
length_ = length;
height_ = height;
Maze::generateMatrix();
}
void Maze::generateMatrix() {
for (unsigned x {}; x < width_; ++x) {
matrix.push_back(std::vector<std::vector<Cell>>());
for (unsigned y {}; y < length_; ++y) {
matrix.at(x).push_back(std::vector<Cell>());
for (unsigned z {}; z < height_; ++z) {
matrix.at(x).at(y).push_back(Cell(x,y,z));
}
}
}
}

How should I make my blocks keep their color even if the global color changes?

I am creating a drawing app with oclPixelGameEngine, and I can't figure out how I should make my blocks(pixels) keep their color, even after the global colors change, when I change the global colors now, every already drawn block changes its color.
*EDIT I forgot to mention this code is executed every frame, and the colors aren't, they are defined only at the start, and when I press some key, they change.
I have tried making a variables inside the for loop, still the problem persists.
class Example : public olc::PixelGameEngine
{
public:
Example()
{
sAppName = "RandomStuff";
}
private:
sCell* world;
int nWorldWidth = 16;
int nWorldHeight = 16;
public:
int fColors[12] =
{
255,0,0,
0,255,0,
0,0,255,
255,255,255
};
int rColor = 255;
int gColor = 255;
int bColor = 255;
int fColorsPos = 0;
bool colorsSet = false;
bool OnUserCreate() override
{
// Provede se hned po zapnutí
world = new sCell[nWorldWidth * nWorldHeight];
return true;
}
bool OnUserUpdate(float fElapsedTime) override
{
// Zapne se každý snímek
float fBlockWidth = 1.0f;
float fSourceX = GetMouseX();
float fSourceY = GetMouseY();
if (GetMouse(0).bReleased)
{
int i = ((int)fSourceY / (int)fBlockWidth) * nWorldWidth + ((int)fSourceX / (int)fBlockWidth);
world[i].exist = !world[i].exist;
}
if (GetKey(olc::Key::RIGHT).bPressed) {
rColor = fColors[fColorsPos];
gColor = fColors[fColorsPos + 1];
bColor = fColors[fColorsPos + 2];
fColorsPos += 3;
if (fColorsPos > 3*4-1)
fColorsPos = 0;
}
//Renderování
Clear(olc::BLACK);
for (int x = 0; x < nWorldWidth; x++)
for (int y = 0; y < nWorldHeight; y++)
{
if (world[y * nWorldWidth + x].exist)
FillRect(x * fBlockWidth, y * fBlockWidth, fBlockWidth, fBlockWidth,olc::Pixel(rColor, gColor, bColor));
}
return true;
}
};
When I created the for loop color variables, I expected them to stay constant for every block, but the blocks still change their colors.
Perhaps you could implement, as a hack, some 'colorCells' to your code, if sCells does not provide a color Palette. (Although the best implementation is to figure out/add color as variables to the sCell class, for the cleanest code).
class colorCells
{
private:
int rColor = 255;
int gColor = 255;
int bColor = 255;
public:
void setColors(int r, int g, int b) {
rColor = r;
gColor = g;
bColor = b;
}
int getR() {
return rColor;
}
int getG() {
return gColor;
}
int getB() {
return bColor;
}
And you would implement that alongside your code, like so:
class Example : public olc::PixelGameEngine
{
public:
Example()
{
sAppName = "RandomStuff";
}
private:
sCell* world;
colorCell* worldColor;
int nWorldWidth = 16;
int nWorldHeight = 16;
public:
int fColors[12] =
{
255,0,0,
0,255,0,
0,0,255,
255,255,255
};
int rColor = 255;
int gColor = 255;
int bColor = 255;
int fColorsPos = 0;
bool colorsSet = false;
bool OnUserCreate() override
{
// Provede se hned po zapnutí
world = new sCell[nWorldWidth * nWorldHeight];
worldColors = new colorCells[nWorldWidth * nWorldHeight];
return true;
}
bool OnUserUpdate(float fElapsedTime) override
{
// Zapne se každý snímek
float fBlockWidth = 1.0f;
float fSourceX = GetMouseX();
float fSourceY = GetMouseY();
if (GetMouse(0).bReleased)
{
int i = ((int)fSourceY / (int)fBlockWidth) * nWorldWidth + ((int)fSourceX / (int)fBlockWidth);
world[i].exist = !world[i].exist;
}
if (GetKey(olc::Key::RIGHT).bPressed) {
rColor = fColors[fColorsPos];
gColor = fColors[fColorsPos + 1];
bColor = fColors[fColorsPos + 2];
if (worldColors[y * nWorldWidth + x].exist) {
worldColors[y * nWorldWidth + x].SetColors(rColor, gColor, bColor);
}
fColorsPos += 3;
if (fColorsPos > 3*4-1)
fColorsPos = 0;
}
//Renderování
Clear(olc::BLACK);
for (int x = 0; x < nWorldWidth; x++)
for (int y = 0; y < nWorldHeight; y++)
{
if (world[y * nWorldWidth + x].exist) {
auto sColor = worldColors[y * nWorldWidth + x];
FillRect(x * fBlockWidth, y * fBlockWidth, fBlockWidth, fBlockWidth,olc::Pixel(sColor.getR(), sColor.getG(), sColor.getB()));
}
}
return true;
}
};
Hopefully that gives you a rough idea about things, the better way to implement it is probably to make colorCells use a tuple to store the colors, but this should be enough to help you understand how to store the colors for now.
Hope that helps!

Vector.push_back(...) read access violation

I don't know why but my program triggers a breakpoint on a line on the first iterations of 2 embedded loops here is the line:
pointerHolder->linkedVertices.push_back(&sphereApproximation.vertices.back());
Here is the section within which this resides (the line is near the bottom):
static const vertice holder[6] = { vertice(0,r,0,0), vertice(r,0,0,0), vertice(0,0,r,0), vertice(0,-r,0,0), vertice(-r,0,0,0), vertice(0,0,-r,0) };
std::vector<vertice> vertices (holder, holder + (sizeof(holder) / sizeof(vertice)));
shape sphereApproximation = shape(0, vertices);
int count;
for (int i = 0; i < 6; i++) {
count = i;
for (int t = 0; t < 5; t++) {
if (count == 5) {
count = 0;
}
else {
count++;
}
if (t != 2) {
sphereApproximation.vertices[i].linkedVertices.push_back(&sphereApproximation.vertices[count]);
}
}
}
bool * newConnection = new bool[pow(sphereApproximation.vertices.size(), 2) - sphereApproximation.vertices.size()]();
vertice * pointerHolder;
for (int i = 0; i < sphereApproximation.vertices.size(); i++) {
for (int t = 0; t < sphereApproximation.vertices[i].linkedVertices.size(); t++) {
if (!newConnection[(i * (sphereApproximation.vertices.size() - 1)) + t]) {
pointerHolder = sphereApproximation.vertices[i].linkedVertices[t];
sphereApproximation.vertices.push_back(newVertice(&sphereApproximation.vertices[i], pointerHolder, accuracyIterator + 1));
for (int q = 0; q < pointerHolder->linkedVertices.size(); q++) {
if (pointerHolder->linkedVertices[q] == &sphereApproximation.vertices[i]) {
pointerHolder->linkedVertices.erase(pointerHolder->linkedVertices.begin() + q);
break;
}
}
sphereApproximation.vertices[i].linkedVertices.erase(sphereApproximation.vertices[i].linkedVertices.begin() + t);
sphereApproximation.vertices[i].linkedVertices.push_back(&sphereApproximation.vertices.back());
std::cout << "gets here" << std::endl;
pointerHolder->linkedVertices.push_back(&sphereApproximation.vertices.back());
std::cout << "does not get here" << std::endl;
sphereApproximation.vertices.back().linkedVertices.push_back(&sphereApproximation.vertices[i]);
sphereApproximation.vertices.back().linkedVertices.push_back(pointerHolder);
}
}
}
I know the declaration for the newVertice(...) subroutine is missing, but I thought it was rather unnecessary, all that needs to be known is that its return type is vertice and it does return a vertice as I have tested. Here are the declerations of the structs I'm using:
struct vertice {
int accuracy;
double x, y, z;
std::vector<vertice*> linkedVertices;
vertice(double x, double y, double z, std::vector<vertice*> linkedVertices) {
this->x = x;
this->y = y;
this->z = z;
this->linkedVertices = linkedVertices;
}
vertice(double x, double y, double z, int accuracy) {
this->x = x;
this->y = y;
this->z = z;
this->accuracy = accuracy;
}
};
struct shape {
double center;
std::vector<vertice> vertices;
shape(double center, std::vector<vertice> vertices) {
this->center = center;
this->vertices = vertices;
}
};
If I've failed to provide anything please drop a comment and I shall amend my question.

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.