Cartesian plane infinite line? - c++

I'm trying to make a program that makes a cartesian plane; you put in input the basic information of the line and he draws the line.
Too bad that it doesn't work well. Basically this is the loop that puts an X char in every point of the line:
for(int x=0;x<MAP_HEIGHT;x++)
{
piano.griglia[x][a*x+b]='X';
}
But it does not work well! here is the result:
http://i.imgur.com/u01Bdk7.jpg
notice how there are 3 lines where it should be only one. Here's the code of the plane, it may help:
class Cartesiano
{
public:
char griglia[MAP_LENGHT+1][MAP_HEIGHT+1];
Cartesiano( void )
{
for(int y=0;y<=MAP_HEIGHT;y++)
{
for(int x=0;x<=MAP_LENGHT;x++)
{
if (y==0)griglia[x][y]='_';
else
{
if(x==0)griglia[x][y]='|';
else griglia[x][y]=' ';
}
}
}
}
void Draw( void )
{
for(int y=MAP_HEIGHT;y>=0;y--)
{
for(int x=0;x<=MAP_LENGHT;x++)cout<<griglia[x][y];
cout<<"\n";
}
}
}piano;
Any ideas?

When your y values exceed 49 (MAP_HEIGHT - 1) you are overflowing your array. If in your draw loop you calculate y=a*x+b and print Z instead of X you'll see the first line is X's and the overflowed errors are all Z's
for(int x=0;x<MAP_LENGTH;x++)
{
int y = a*x+b;
if(y<MAP_HEIGHT) {
piano.griglia[x][y]='X';
} else {
piano.griglia[x][y]='Z';
}
}
This is due to the way memory for the arrays is stored in C++, it just happens writing outside one array here causes you to write into the next one. In general doing this will crash your program.
Also note that here the x loop should be over MAP_LENGTH.
I would also strongly advise getting a proper graphics library

Related

Program to find greatest common divisor

Here's a c++ program i tried to write for the above question.Our teacher told us to use a for loop.
void main()
int A[30],B[30],m,n,i,j,x,z;
cout<< "enter two numbers";
cin>>m>>n;
for(i=1,j=0;i<=m,j<30;i++,j++)
{
if(m%i==0)
{ A[j]=i;
z=j;
}
}
for(i=1,j=0;i<=n,j<30;i++,j++)
{
if(n%i==0)
{ B[j]=i;
x=j;
}
}
for(i=z;i>=0;--i)
{
for(j=x;j>=0;--j)
{
if(A[i]==B[j])
{ cout<<"gcd="<<A[i];
}
}
}
}
The output displays " Enter two numbers:" and when i entered 15 and 3, the result i got was a blinking cursor. Working through the program, I realised that the divisors for each number when stored in the arrays of A and B were not stored continuously or had gaps in between. If there isn't anything in the memory for say A[11], what happens when you check it against another variable with a number? Can somebody please modify this to make it work and tell me what's wrong? I am new to programming, so excuse my program if it is clumsy.
Andreas has pointed out that there are other ways to achieve the goal of finding the gcd, but the point of the exercise is to get a better handle on some basic programming constructs. So lets go with your approach.
Your idea is to compute the two lists of divisors and then compare them. As you say, having a list with gaps in makes this harder.
So adapt your loop, only increment the storage index when you've stored something
for(i=1,j=0;i<=m && j<30;i++) // need the && here; a comma means something different
{
if(m%i==0)
{ A[j++]=i;
z=j;
}
}
Second, you have a typo you're not storing in B, so fix that
for(i=1,j=0;i<=n && j<30;i++)
{
if(n%i==0)
{ B[j++]=i; //B here not A
x=j;
}
}
That should help.
Try this:
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
As taken from here: https://codereview.stackexchange.com/questions/66711/greatest-common-divisor

c++ vector push_back access violation

I'm struggling with a random exception when using std::vector.
Here are the main elements :
struct Stroke
{
std::vector<vec2> points;
Pixel color;
std::vector<unsigned int> pixelIds;
};
void myFunc()
{
while (strokes.size() < 5000)
{
if (/*A condition that is always met at some point*/)
{
break;
}
//Some code
newStroke->pixelIds.clear();
newStroke->pixelIds.resize(0);
strokes.push_back(newStroke);
}
for (int i = 0; i < strokes.size(); ++i)
{
drawStroke(strokes[i]);
}
}
void drawStroke(Stroke * currentStroke)
{
std::vector<int> roundIds;
//Fill roundIds
//Some loops and conditions
for (int i = 0; i < roundIds.size(); ++i)
{
if (/*Check condition*/)
{
// Exception is raised deeper in the stack here
currentStroke->pixelIds.push_back(currentRoundId);
}
}
}
I left out big parts of the code that shouldn't really affect this because I have no idea where the problem could come from (so I'd have to copy/paste the whole code :D). In the last line I randomly get an Access violation deeper in the stack (_Orphan_Range method of std::vector).
I don't see anything wrong with currentStroke in the watch, the points vector is looking normal, color too, I guess that some internal values of pixelIds are broken (_Myfirst=0x000000000038c700 _MyEnd=0x000000000038c74c doesn't look too good to me but I'm not sure).
I'm not very experienced with the details of STL and I don't know what to look for especially since the vector is only holding unsigned int values, not some fancy weird class or structure and I have no idea what could ever mess up with the internal values of a vector.
Any suggestion or advice will be appreciated!
Thanks!
myFunct has an endless loop that fills stoke vector until you get out of memory.

About checking fields around in 2 dimensional array [C++]

I know it might sound stupid, but i got to ask.
It's about that easy thing.
You have a 2 dimensional array, with elements inside or empty, then you get some location(x and y) and i have to draw one field from the free fields around.
I know how to do it, it just doesn't seems ... elegant or nice.
The way i was doing it was checking if i'm on the max left, max right, top, bottom, etc. Then if there is something in fields around, and then rand().
It's just so long and seems so unpleasent.
I don't know if there's shorter way? Thanks.
And sorry for my english, doing my best.
There might be some performance issues. The most critic situation is when you have point [x, y] in the corner, rand() can possibly select the invalid elements multiple times, so you have to rand() and check again.
The way I'd do it, is to check for available neighbours and push each valid neighbour into std::vector. After that, there's only one random number generation which chooses one element within this vector:
std::vector<Coordinate> validNeighbours;
// Coordinate is a struct with x and y integers, you can use std::pair<int, int> or the very pointers to the elements
if(/* has neighbour to the left*/)
validNeighbours.push_back(Coordinate(x - 1, y));
// check in other directions
Coordinate c = validNeighbours[std::rand() % validNeighbours.size()];
You might also want to check whether validNeighbours is not empty before performing the modulo, in case you have just 1x1 array (validNeighbours.size() is 0).
Instead of using an array of dimensions height and width, I would use an array of dimensions height+2 and width+2. Then you can fill the border cells with whatever dummy value makes sense.
It's a school project, so i can't use STL. --- to one of the anwsers.
But i got my own solution :)
I made my structure Vector( but it's like position vector, not array-vector), and i got this code, anyway i think it's the shortest way, thanks for all the help:
Vector Organism::FindFreeSpace()
{
int height=home->GetHeight();
int width=home->GetWidth();
Vector* choices;
Vector shift;
if(location.x==0 || location.x==width-1)
{
if(location.y==0 || location.y==height-1)
{
choices= new Vector[2];
choices[0]=( location.x==0 ? Vector(1,0) : Vector(-1,0));
choices[1]=( location.y==0 ? Vector(0,1) : Vector(0,-1));
ShuffleChoices(choices, 2);
for(int h=0;h<2;h++)
{
if(home->IsFree(choices[h]+location)==true)
{
location+=choices[h];
shift=choices[h];
delete[] choices;
return shift;
}
}
}
else
{
choices=new Vector[3];
choices[0]=( location.x==0 ? Vector(1,0) : Vector(-1,0));
choices[1]=Vector(0,1);
choices[2]=Vector(0,-1);
ShuffleChoices(choices, 3);
for(int h=0;h<3;h++)
{
if(home->IsFree(choices[h]+location)==true)
{
location+=choices[h];
shift=choices[h];
delete[] choices;
return shift;
}
}
}
}
else if(location.y==0 || location.y==height-1)
{
choices=new Vector[3];
choices[0]=( location.y==0 ? Vector(0,1) : Vector(0,-1));
choices[1]=Vector(1,0);
choices[2]=Vector(-1,0);
ShuffleChoices(choices, 3);
for(int h=0;h<3;h++)
{
if(home->IsFree(choices[h]+location)==true)
{
location+=choices[h];
shift=choices[h];
delete[] choices;
return shift;
}
}
}
else
{
choices=new Vector[4];
choices[0]=Vector(0,1);
choices[1]=Vector(1,0);
choices[2]=Vector(-1,0);
choices[3]=Vector(0,-1);
ShuffleChoices(choices, 4);
for(int h=0;h<4;h++)
{
if(home->IsFree(choices[h]+location)==true)
{
location+=choices[h];
shift=choices[h];
delete[] choices;
return shift;
}
}
}
return Vector(0,0);
}
I know, you won't get it all, but you should get the idea of what have i done.

Array setup in constructor means failure later on

I had an issue where my code segfaulted on attempting to use the size() function of a list. On the advice of stackoverflow :-) I constructed a minimum case in which the segfault occurs (on the call inventory.size() below). It is:
#include <list>
class Thing {};
class Player {
private:
int xpCalcArray[99];
std::list<Thing*> inventory;
public:
Player();
int addToInv(Thing& t); // return 1 on success, 0 on failure
};
Player::Player() {
// set up XP calculation array
for (int i=1; i<100; i++) {
if (i<=10) {
xpCalcArray[i] = i*100;
}
if (i>10 && i<=50) {
xpCalcArray[i] = i*1000;
}
if (i>50 && i<=99) {
xpCalcArray[i] = i*5000;
}
}
}
int Player::addToInv(Thing& t) {
if (inventory.size() == 52) {
return 0;
} else {
inventory.push_back(&t);
}
return 1;
}
int main(int argc, char *argv[]) {
Thing t;
Player pc;
pc.addToInv(t);
return 1;
}
I notice that when I remove the setting up of the array in the Player cosntructor, it works fine, so this looks to be the problem. What am I doing wrong?
You are accessing your array out of bounds, which results in undefined behaviour. The valid index range for this array
int xpCalcArray[99];
is 0 to 98. You are accessing index 99 here:
if (i>50 && i<=99) {
xpCalcArray[i] = i*5000;
}
Your outer loop should be
for (int i=0; i<99; i++) { ... }
Note I start from 0, although it is an assumption that you actually want to access the first element.
Then your final condition can be simplified to
if (i>50) {
xpCalcArray[i] = i*5000;
}
If you intended to use a size 100 array, then you need
int xpCalcArray[100];
then loop between int i=0; i<100;.
You are accessing outside the bounds of your array. Doing so causes undefined behaviour and so there is no logical explanation for anything that occurs afterwards. The size of your array is 99 and so the last index is 98. Your for loop goes up to 99, however.
Either make your array size 100:
int xpCalcArray[100];
Or change your for condition to i < 99.
You are overwriting your array of 99 ints by attempting to modify the 2nd→100th elements (rather than 1st→99th).
In your case, this happens to overwrite some memory within the std::list<Thing*> (which exists in memory directly after the array — not always, but evidently for you today) and thus, when you try to use the list, all hell breaks loose when its internal member data is no longer what it thought it was.
You xpCalcArray is defined from 0 up to 98 (being 99 elements large).
Your loop goes from 0 up to 99, taking 100 steps.
The last loop cycle, writes xpCalcArray at location 99, which does not exist. This (indirectly) results in your segmentation fault as shown by the answer of Lightness Races in Orbit.
So, increase the size of xpCalcArray by 1:
int xpCalcArray[100];

Deleting 2d array in C++

Can some one tell me what is wrong in the for loop? When I run it, it interrupts. I tried to debug to see what is wrong, I noticed that in the for loop it just stops:
#define MAX_POPULATION 64
float **tr_pop;//Tournament candidates
float **matingPool;//Mating pool
tr_pop=new float *[m];
matingPool=new float *[m];
for(l=0;l<m+1;l++)//allocating
{
tr_pop[l]=new float[MAX_POPULATION];
matingPool[l]=new float[MAX_POPULATION];
}
for ( int r = 0; r < row; ++r )//deleting
{
delete [] matingPool[r];//Stops here (not ending program just frozen)
delete [] tr_pop[r];
}
delete [] tr_pop;
delete [] matingPool;
=======OK. PROBLEM SOLVED=======
Here is the reason:
I just changed the MAX_POPULATION into the MAX_POPULATION+1 and it worked.
for(l=0;l<m+1;l++)
{
tr_pop[l]=new float[MAX_POPULATION+1];
matingPool[l]=new float[MAX_POPULATION+1];
}
Because in another function I think I was doing violation:
void crossover()
{
int p1,p2,i,j;float tempBit;
p1=m/3;
p2=(2*m)/3;
for(j=0;j<MAX_POPULATION;j++)
{
for(i=p1;i<p2;i++)
{
tempBit=matingPool[i][j];
matingPool[i][j]=matingPool[i][j+1];//THE VIOLATION POINT (I THINK)
matingPool[i][j+1]=tempBit;
}
j++;
}
As you can see, when j = MAX_POPULATION at the end of the loop, i was trying to reach MAX_POPULATION + 1. So I changed the allocations for columns, and the problem solved :)
You're running into undefined behavior:
for(l=0;l<m+1;l++)//allocating
{
tr_pop[l]=new float[MAX_POPULATION];
}
should be
for(l=0;l<m;l++)//allocating
{
tr_pop[l]=new float[MAX_POPULATION];
}
You're allocating m elements for each of the arrays and try to access m+1.
You are allocating m float* but in for loop you are iterating from 0..m while allocating memory, it should from 0..m-1. For that you need to chnage the for loop to : for(l=0;l<m;l++).