When I'm comparing an element in std::vector to char, I randomly get this error sometimes when running to program (about once every five times):
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: 13 at address: 0x0000000000000000
0x0000000100017c49 in randomCaveGenerator (p=#0x7fff5fbff51c, q=#0x7fff5fbff518, seed=1234567) at src/main.cpp:198
198 if (lm.map[1][i][j] == '0')
v is defined as a std::vector with all elements filled. I know this error usually means it is pointing to a null pointer but I know there shouldn't be one.
I'm using Mac OS X 10.8, gdb to debug, and Apple LLVM version 4.2 (based on LLVM 3.2svn) to compile.
Edit
The code that I'm using:
typedef std::vector< std::vector<char> > MapGrid;
struct LevelMap
{
std::string name;
std::vector<MapGrid> map;
sf::Vector2u size;
};
LevelMap randomCaveGenerator(int p=64, int q=64, unsigned long seed=1)
{
if (p < 64)
p = 64;
if (q < 64)
q = 64;
int groundLevel = 12;
srand(seed);
sf::Vector2u size(p, q);
std::vector<MapGrid> mapG(3);
for (int i = 0; i < 3; i++)
{
mapG[i] = MapGrid(size.x, std::vector<char>(size.y));
for (int y = 0; y < size.y; y++)
{
for (int x = 0; x < size.x; x++)
{
mapG[i][x][y] = '0';
}
}
}
for (int y = 0; y < size.y; y++)
{
for (int x = 0; x < size.x; x++)
{
mapG[0][x][y] = 'v'; // Void Tile
}
}
for (int y = 0; y < size.y; y++)
{
for (int x = 0; x < size.x; x++)
{
mapG[2][x][y] = '0'; // Air Tile
}
}
for (int y = groundLevel; y < size.y; y++)
{
for (int x = 0; x < size.x; x++)
{
int e = 23;
if (2+(rand()%e)< e/2)
mapG[1][x][y] = 'd';
else
mapG[1][x][y] = '0';
}
}
LevelMap lm;
lm.name = "Random Map";
lm.map = mapG;
lm.size = size;
for (int i = 0; i < 12; i++)
doSimStep(lm);
for (int i = 1; i < lm.size.x - 2; i++)
{
for (int j = 1; j < 12+groundLevel; j++)
{
if (lm.map[1][i][j] == '0') // PART WHERE THE ERROR IS
continue;
else
{
lm.map[1][i][j] = 'g';
lm.map[2][i][j-1] = 'w';
i++;
j = 1;
}
}
}
for (int i = 1; i < lm.size.x - 2; i++)
{
for (int j = groundLevel; j < lm.size.y - 2; j++)
{
if (lm.map[1][i][j] == 'd')
{
if (rand()%120 == 0)
lm.map[2][i][j] = 'p';
}
}
}
for (int i = 0; i < lm.size.y; i++)
{
lm.map[1][0][i] = 'X';
lm.map[1][lm.size.x-2][i] = 'X';
lm.map[2][0][i] = '0';
lm.map[2][lm.size.x-2][i] = '0';
}
for (int i = 0; i < lm.size.x; i++)
{
lm.map[1][i][0] = 'X';
lm.map[1][i][lm.size.y-2] = 'X';
lm.map[2][i][0] = '0';
lm.map[2][i][lm.size.y-2] = '0';
}
return lm;
}
With no source code apart from the error message
if (v[i] == '0')
I can only imagine i >= v.size()
You might want to consider using iterators to access your vector, so you don't step off the end.
Related
enter image description here
i have this expression of a tour of worker and i tried to coded it and i don't know if it is correct or no because i have many errors so can someone help me ,
X[w][w][i][j] is a decision variable , p [i][j] is the weight of processing arc from i to j and d[i][j] is a distance
this is my proposition of code
compteur = 0;
IloFloatVarArray2 CW(env, W);
for (w = 0; w < W; w++)
{
CW[w] = IloFloatVarArray(env, W, 0.0, INFINITY);
model.add(CW[w]);
#ifdef DEBUG
for (w = 0; w < W; w++)
{
sprintf(varname, "CW_%d_%d", w, w);
CW[w][w].setName(varname);
compteur++;
}
}
#endif
#ifdef DEBUG
printf("compteur cw =%d\n", compteur);
#endif
IloExpr CW[w][w](env);
for (i = 0; i < A; i++)
for (j = 0; j < A; j++)
CW[w][w] += d[i][j] * xW[w][i][j][w];
for (i = 0; i < A; i++)
for (j = 0; j < A; j++)
CW[w][w] += Parc[i][j] * xW[w][i][j][w];
for (i = 0; i < A; i++)
for (j = 0; j < A; j++)
CW[w][w] += 1 * xW[w][i][j][w];
model.add(env, CW[w][w]);
CW[w][w].end();
you have to create a 2-D array of expressions, fill it, and then constrain the expressions by some constraints. For example:
#include <ilcp/cp.h>
int main() {
typedef IloArray<IloNumExprArray> IloNumExprArray2;
IloEnv env;
IloInt n = 4;
IloNumExprArray2 c(env, n);
IloIntVarArray var(env, n, 0, n-1);
for (IloInt x = 0; x < n; x++) {
c[x] = IloNumExprArray(env, n);
for (IloInt y = 0; y < n; y++) {
c[x][y] = IloNumExpr(env, 0);
c[x][y] += var[x] * var[y];
}
}
IloModel mdl(env);
for (IloInt x = 0; x < n; x++) {
for (IloInt y = 0; y < n; y++) {
mdl.add(c[x][y] ==1);
}
}
IloCP cp(mdl);
cp.startNewSearch();
while (cp.next()) {
cp.out() << cp.domain(var) << std::endl;
}
cp.end();
env.end();
return 0;
}
I am trying to create a simulation of conway's game of life.
I keep getting a "vector subscript out of range" error after about 300 generation and I don't understand the reason. From what I could gather it's caused by using an invalid index. The most likely section is the first part of the draw function where I find empty rows and replace them with "\n" to save time.
I've started learning to code not too long ago so I may be making baby mistakes.
Edit: visual studio point the error after the third for loop in the frame function, on if (emptyRows[m] == i)
Here's the full code :
#include <array>
#include <time.h>
#include <vector>
const int WIDTH = 150;
const int HEIGHT = 50;
bool table[WIDTH][HEIGHT];
bool tableNew[WIDTH][HEIGHT];
std::string buffer;
int total;
int counter = 0;
std::vector<int> emptyRows;
int numberOfNeighbours(int Y, int X) {
if (X == 0 || Y == 0 || X == WIDTH || Y == HEIGHT)
return 2;
total = 0;
for (int i = -1; i < 2; i++) {
for (int j = -1; j < 2; j++) {
if (table[X + j][Y + i] == true)
total++;
}
}
total -= table[X][Y];
return total;
}
void draw() {
srand((int)time(0));
int m = 0;
bool check = 0;
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
if (table[j][i] == 1)
check = 1;
}
if (check == 0)
emptyRows.push_back(i);
else
check = 0;
}
for (int i = 0; i < HEIGHT; i++) {
if (emptyRows.size() >= 1) {
if (emptyRows[m] == i) {
buffer.append("\n");
m++;
continue;
}
}
for (int j = 0; j < WIDTH; j++) {
if (table[j][i] == 1) buffer.push_back('#');
else buffer.push_back(' ');
}
buffer.append("\n");
}
std::cout << buffer;
std::cout << std::endl << "Generazione numero:" << counter;
emptyRows.erase(emptyRows.begin(), emptyRows.end());
buffer.erase(buffer.begin(), buffer.end());
m = 0;
}
void reset() {
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
table[j][i] = tableNew[j][i];
}
}
}
void logic() {
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
int k = numberOfNeighbours(i, j);
if (table[j][i] == 0 && k == 3)
tableNew[j][i] = 1;
else if (table[j][i] == 1 && k != 2 && k != 3)
tableNew[j][i] = 0;
else
tableNew[j][i] = table[j][i];
}
}
}
int main(){
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
if ((rand() % 2) == 1)
table[j][i] = 1;
}
}
while (true) {
counter++;
draw();
logic();
reset();
system("cls");
}
return 0;
}
I have written a simple battleship game in C++. After several iterations of the game, one of the strings in a "Player" object is changed. This change is several null characters are added to the end of the string. Otherwise the rest of the object is untouched. For example if the player type is "cpu", the player type switches to "cpu\0\0\0\0\0\0\0\0". I believe the line of code causing the problem is:
currPlayer->getStrategy().getNextAttack(nextPlayer->getBoard(1));
Here is the code for getNextAttack():
int Strategy::getNextAttack(Board enemyBoard) {
//clear prob board
for(int i = 0; i < 100; i++) {
probBoard[i] = 0;
}
//reset largest ship
largestShip = 0;
//assign largest ship
for(int i = 0; i < 100; i++) {
Ship currShip = enemyBoard.getShipByCoord(i);
if(!currShip.isSunk()) { //if ship is still afloat
if(currShip.getSize() > largestShip) { largestShip = currShip.getSize(); } //reassign largest ship on board
}
}
//assign base prob
std::vector<int> allPossible;
//for all horiz coords
for(int i = 0; i < 10; i++) {
for(int j = 0; j < (10 - largestShip +1); j++) {
for(int k = 0; k < (largestShip); k++) {
if(!enemyBoard.beenHit((i*10) + j + k) || (enemyBoard.beenHit((i*10) + j + k) && !enemyBoard.getShipByCoord((i*10) + j + k).isSunk())) { //if not hit or if hit but contains a ship that is not sunk
allPossible.push_back((i*10) + j + k);
}
else {
for(int m = 0; m < k; m++) {
allPossible.pop_back(); //should delete last element
}
break;
}
}
//for all vert coords
for(int z = 0; z < (largestShip); z++) {
if(!enemyBoard.beenHit(((j+z)*10) + i)) {
allPossible.push_back(((j+z)*10) + i);
}
else {
for(int m = 0; m < z; m++) {
allPossible.pop_back(); //should delete last element
}
break;
}
}
}
}
for(int p = 0; p < allPossible.size(); p++) {
probBoard[allPossible[p]] += 1;
}
//add improvements based on hits
for(int i = 0; i < 10; i++) {
for(int k = 0; k < 10; k++) {
int currCoord = (i*10) + k;
int leftCoord = (i*10) + k-1;
int rightCoord = (i*10) + k+1;
int upCoord = ((i-1)*10) + k;
int downCoord = ((i+1)*10) + k;
if(enemyBoard.beenHit(currCoord) && (enemyBoard.getShipByCoord(currCoord).getName() != "") && !enemyBoard.getShipByCoord(currCoord).isSunk()) { //currCoord is a coordinate that has been hit, contains a ship and is not sunk
if((enemyBoard.beenHit(leftCoord) || enemyBoard.beenHit(rightCoord)) && (enemyBoard.getShipByCoord(leftCoord) == enemyBoard.getShipByCoord(currCoord) || enemyBoard.getShipByCoord(rightCoord) == enemyBoard.getShipByCoord(currCoord))) { //if space to left or right is hit and the same ship
//increment only the left and right
if(!enemyBoard.getShipByCoord(currCoord).isSunk()) { //ship cannot be sunk as well
probBoard[leftCoord] += 25;
probBoard[rightCoord] += 25;
}
}
else if((enemyBoard.beenHit(upCoord) || enemyBoard.beenHit(downCoord)) && (enemyBoard.getShipByCoord(upCoord) == enemyBoard.getShipByCoord(currCoord) || enemyBoard.getShipByCoord(downCoord) == enemyBoard.getShipByCoord(currCoord))) { //if space on top or bottom is hit and the same ship and not sunk
//increment only the top and bottom
if(!enemyBoard.getShipByCoord(currCoord).isSunk()) { //ship cannot be sunk as well
probBoard[upCoord] += 25;
probBoard[downCoord] += 25;
}
}
//if no direct spaces in any direction to hit coord, increment top, bot, left, and right equally
else {
probBoard[upCoord] += 20;
probBoard[downCoord] += 20;
probBoard[leftCoord] += 20;
probBoard[rightCoord] += 20;
}
}
}
}
//marks odds at 0 if already fired upon
for(int n = 0; n < 100; n++) {
if(enemyBoard.beenHit(n)) {
probBoard[n] = 0;
}
}
//find next best attack coord based on prob board
int highestValue = 0;
std::vector<int> highestSpaces;
for(int j = 0; j < 100; j++) {
if(probBoard[j] > highestValue) { highestValue = probBoard[j]; }
}
for(int r = 0; r < 100; r++) {
if(probBoard[r] == highestValue) {
highestSpaces.push_back(r);
}
}
srand(static_cast<unsigned int>(time(NULL)));
int randNum = rand() % highestSpaces.size();
return highestSpaces[randNum];
}
Thank you for reading and any help!
This looks like it will go out of the array bounds at the edges when the row or column is 0 or 9:
probBoard[upCoord] += 20;
probBoard[downCoord] += 20;
probBoard[leftCoord] += 20;
probBoard[rightCoord] += 20;
Here's the problem https://www.hackerrank.com/challenges/extra-long-factorials
Here's my code
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
int product[200];
for (int i = 0; i < 200; i++)product[i] = 0;
product[0] = 1;
for (int i = 1; i <= n; i++){
int a[200], res[200];
for (int j = 0; j < 200; j++)a[j] = 0, res[j] = 0;
int n = i;
int k = 0;
while(n != 0){
a[k] = n % 10;
n = n / 10;
k++;
}
int at[200][200];
for (int p = 0; p < 200; p++){
for (int h = 0; h < 200; h++){
at[p][h] = 0;
}
}
int carry = 0;
for (int x = 0; x < 200; x++){
for (int d = 0; d < 200; d++){
at[x][x+d] = ((product[d] * a[x]) % 10) + carry;
carry = (product[x] * a[d]) / 10;
}
}
int carry2, temp;
for (int u = 0; u < 200; u++){
temp = 0;
for (int e = 0; e < 200; e++){
temp += at[e][u];
}
temp = (temp + carry2);
carry2 = temp/10;
res[u] = temp %10;
product[u] = res[u];
}
}
int f = 0;
for (; f < 200; f++){
if(product[200-f-1] != 0)break;
}
for (; f < 200; f++){
cout << product[200-f-1];
}
return 0;
}
It runs fine on gcc on my mac and gives a correct answer. However it gives a runtime error on the online judge as well as ideone.
I've debugged the code and the error is caused by cin >> n; It runs fine without it and gives a correct answer (which is 1). The test input that caused the error is 25 so it's not a big number. I dont know exactly what's the problem or how is it causing the error. Thank you.
This is the problem:
at[x][x+d] = ...
because both x and d run from 0 to 200, but at is an array on the stack, with size: [200][200] so obviously x+d will overwrite the code coming after the array declaration.
This is a classical buffer overflow :)
(Obviously, initializing carry2 won't hurt either, but not doing that will not give the core dump at 0x0, just some unexpected behaviour)
all the arrays in this code are complex type in this code and the running time for this for loop is about 1 min. Ktemp is an array with size 141*1202*141. could anyone help me to optimize this code and save the running time?
complex<double> ***P1;
P1 = new complex<double>**[141];
for (i = 0; i < num_y; i++)
{
P1[i] = new complex<double> *[1202];
for (j = 0; j < tsize; j++)
{
P1[i][j] = new complex<double>[141];
}
}
for (int zz = 1; zz < 20; zz++)//in z direction
{
for (i = 0; i < 141; i++)
{
for (j = 0; j < 1202; j++)
{
for (k = 0; k < 141; k++)
{
if (Ktemp[i][j][k].real() <= 0)
{
P1[i][j][k] = 0;
}
else
{
P1[i][j][k] = excit_pfft[i][j][k] * expn[i][j][k];
}
}
}
}
excit_pfft = P1;
}
my second question is about rewriting matlab function 'fftshift' with C++. I have finished the code, but it seems not that efficient. could anyone help me rewrite this code? my code is attached below:
complex<double> ***fftw_shift(complex<double> ***te, int a, int b, int c)
{
complex<double> ***tempa;
tempa = new complex<double> **[a];
for (i = 0; i < a; i++)
{
tempa[i] = new complex<double> *[b];
for (j = 0; j < b; j++)
{
tempa[i][j] = new complex<double>[c];
}
}
/*for the row*/
if (c % 2 == 1)
{
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c / 2; k++)
{
tempa[i][j][k] = te[i][j][k + c / 2 + 1];
tempa[i][j][k + c / 2] = te[i][j][k];
tempa[i][j][c - 1] = te[i][j][c / 2];
}
}
}
}
else
{
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c / 2; k++)
{
tempa[i][j][k] = te[i][j][k + c / 2];
tempa[i][j][k + c / 2] = te[i][j][k];
}
}
}
}
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
te[i][j][k] = tempa[i][j][k];
}
}
}
/*for the column*/
if (b % 2 == 1)
{
for (i = 0; i < a; i++)
{
for (j = 0; j < b / 2; j++)
{
for (k = 0; k < c; k++)
{
tempa[i][j][k] = te[i][j + b / 2 + 1][k];
tempa[i][j + b / 2][k] = te[i][j][k];
tempa[i][b - 1][k] = te[i][b / 2][k];
}
}
}
}
else
{
for (i = 0; i < a; i++)
{
for (j = 0; j < b / 2; j++)
{
for (k = 0; k < c; k++)
{
tempa[i][j][k] = te[i][j + b / 2][k];
tempa[i][j + b / 2][k] = te[i][j][k];
}
}
}
}
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
te[i][j][k] = tempa[i][j][k];
}
}
}
/*for the third dimension*/
if (a % 2 == 1)
{
for (i = 0; i < a / 2; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
tempa[i][j][k] = te[i + a / 2 + 1][j][k];
tempa[i + a / 2][j][k] = te[i][j][k];
tempa[a - 1][j][k] = te[a / 2][j][k];
}
}
}
}
else
{
for (i = 0; i < a / 2; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
tempa[i][j][k] = te[i + a / 2][j][k];
tempa[i + a / 2][j][k] = te[i][j][k];
}
}
}
}
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
te[i][j][k] = tempa[i][j][k];
}
}
}
return (te);
}
Since you are repeatedly multiplying by the values in expn (i.e. calculating an exponent) you can do this more efficiently using the pow function and get rid of the zz loop:
for (i = 0; i < 141; i++)
{
for (j = 0; j < 1202; j++)
{
for (k = 0; k < 141; k++)
{
if (Ktemp[i][j][k].real() <= 0)
{
excit_pfft[i][j][k] = 0;
}
else
{
excit_pfft[i][j][k] = excit_pfft[i][j][k] * pow(expn[i][j][k], 20);
}
}
}
}
Your code also seems to have a memory leak because you assign P1 to excit_pfft, but never free the previous contents of excit_pfft. You don't need to have the P1 temporary array in any case once you get rid of the outer loop.
I'm not sure of the internals of the complex pow() function, but you can calculate the (scalar) exponent of a complex number geometrically by converting it to polar co-ordinates (angle + distance scalar), then multiplying the angle by the power and raising the distance to the power, then converting back. So it's a lot faster than repeated multiplication.
First (will probably give you a big performance boost), get rid of the pointer arrays if you know beforehand the size of your arrays and simply allocate them in the stack:
complex<double> P1[141][1202][141];
Instead of :
complex<double> ***P1;
P1 = new complex<double>**[141];
for (i = 0; i < num_y; i++)
{
P1[i] = new complex<double> *[1202];
for (j = 0; j < tsize; j++)
{
P1[i][j] = new complex<double>[141];
}
}
And since I don't know exactly what this does, I'm assuming this:
for (int zz = 1; zz < 20; zz++)//in z direction
{
for (i = 0; i < 141; i++)
{
for (j = 0; j < 1202; j++)
{
for (k = 0; k < 141; k++)
{
if (Ktemp[i][j][k].real() <= 0)
{
P1[i][j][k] = 0;
}
else
{
P1[i][j][k] = excit_pfft[i][j][k] * expn[i][j][k];
}
}
}
}
excit_pfft = P1;
}
Could become this:
for (int zz = 1; zz < 20; zz++)//in z direction
{
for (i = 0; i < 141; i++)
{
for (j = 0; j < 1202; j++)
{
for (k = 0; k < 141; k++)
{
if (Ktemp[i][j][k].real() <= 0)
{
P1[i][j][k] = 0;
}
else
{
P1[i][j][k] = P1[i][j][k] * expn[i][j][k];
}
}
}
}
}
If this cannot be done than I'll need a more broad chunk of this code to analyze excit_pfft, etc.
A huge performance boost you could have is to use Worker Threads and run this last code multithreaded.
The same goes for our second question, Worker Threads should do it.
EDIT:
On second though, the stack won't be able to handle that much variables.
I'd recommend using vector<vector<vector<complex<double> > > > instead.