Stack overflow when manipulating Bi-dimensional integer array - c++

I wrote this C++ program to sort an integer matrix using selection sort. I tried to compile and run the program. But I ran into a stack overflow error and the message also said something about an access violation writing location .
I tried the following steps:
Tried reducing the array size from 50 x 50 to 10 x 10.
Tried heap allocation to the resultant array (using new).
Tried declaring the resultant array as static.
Tried examining the Memory option in Debug Menu for that particular memory
location(but couldn't make sense of it).
Tried examining the chkstk.asm file that the IDE automatically opened.
But all these efforts were of no use.
This is the part of the source code involved in the runtime error.
void SelectionSort(int matrix[][10], int rowMax, int colMax)
{
//Runtime error was pointed over here.
int smallest, temp, position, count = 0;
int resultant[10][10];
for (int row = 0; row < rowMax; row++)
{
for (int j = 0; j < rowMax - 1; j++)
{
smallest = matrix[row][j];
position = j;
for (int k = j + 1; k < rowMax; k++)
{
if (matrix[row][k] < smallest)
{
smallest = matrix[row][k];
position = k;
}
}
temp = matrix[row][j];
matrix[row][j] = matrix[row][position];
matrix[row][position] = temp;
}
}
for (int i = 0; i < rowMax; i++)
for (int j = 0; j < colMax; j++)
resultant[i][j] = matrix[j][i];
if (count == 0)
{
SelectionSort(resultant, rowMax, colMax);
count++;
}
else
{
std::cout << "The sorted matrix is: " << std::endl;
for (int i = 0; i < rowMax; i++)
{
for (int j = 0; j < colMax; j++)
{
std::cout << matrix[i][j] << " ";
}
std::cout << "\n";
}
}
}
These were the messages that were thrown.
Exception thrown at 0x00007FF79D763488 in Sorting Algorithm Benchmarking Program.exe: 0xC0000005: Access violation writing location 0x000000BFBF600000. occurred
and
Unhandled exception at 0x00007FF79D763488 in Sorting Algorithm Benchmarking Program.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x00000058CE0B3000). occurred
I expected the sorted matrix to be printed in the console.
For example, if the unsorted matrix is:
1 9 5
8 3 6
7 4 2
then the output should be:
1 2 3
4 5 6
7 8 9
I would request you not to send complicated template-based suggestions, as I am in the intermediate level of C++ programming.
Thanks in advance!

Related

occasional *** stack smashing detected*** with c++

I have following C++ code for bubble sort.
This code compiles without any error, but when I re compile and run, I get
*** stack smashing detected ***: terminated
As a C++ newby I want to know ,why do I get these occasional errors when it runs?
void bubbleSort(int eatenPanCakes[10],int arrSize){
int temp=0;
for(int i=0;i<arrSize-1;i++){
for (int j = 0; j < arrSize-i; j++)
{
if (eatenPanCakes[j] > eatenPanCakes[j+1])
{
temp = eatenPanCakes[j+1];
eatenPanCakes[j+1] = eatenPanCakes[j];
eatenPanCakes[j] = temp;
}
}
}
}
Environment : g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
There is a bug in my code : for (int j = 0; j+1 < arrSize-i; j++) would be the right algorithm and that works without error.
Ref-1,Ref-2
You program is accessing array beyond its size which is an undefined behavior. Check this for loop condition:
for (int j = 0; j < arrSize-i; j++)
[I believe, arrSize value is 10 as the type of eatenPanCakes array is int [10]].
when i is 0, arrSize-i value is 10 and in last iteration when j value is 9, this statement
if (eatenPanCakes[j] > eatenPanCakes[j+1])
access j+1th element of eatenPanCakes array which is element at index 10. Note that an array of size 10 will have valid index from 0 to 9.
Instead, the condition in for loop should be
for (int j = 0; j < arrSize - i - 1; j++)
^^^
because the jth element is compared with element ahead of it in the array.

c++ confusing state variable behaviour

I have a class "CardT" the contains a suit and number stored by an enum value. For the use of solitaire i create a deck of 52 of these cards with each value. I also have a "tableau" class that stores a set of these cards for the solitaire tableau, my board class contains an array of 8 of these. After placing the values in the array and printing to check for correctness, it gives a correct output. But if i then call another function right after that prints the exact same thing, i get very different values.
int main(){
Board b;
b.setUp(); //setUp deck and add to tableau arrays
b.printTab(4); //print the fourth one again
}
Where deck gets setup
void Board::setUp(){
//here i setup all 52
CardT deck[52];
int c = 0;
for (int i = 0; i <= 3; i++)
for (int j = 1; j <=13;j++){
deck[c] = CardT(static_cast<CardSuit>(i),static_cast<CardNum>(j));
c++;
}
//shuffle
std::random_shuffle(&deck[0],&deck[52]);
CardT tabls[8][13];
for (int i = 0; i < 4; i++)
for (int j = 0; j < 8; j++)
tabls[i][j] = deck[j + i*8]; //the first 4 piles that contain 8 cards
for (int i = 4; i < 8; i++)
for (int j = 0; j < 7;j++)
tabls[i][j] = deck[j + i*8]; //last four with seven
for (int i = 0; i < 4; i++)
this->tableauPiles[i] = TableauPileT(tabls[i],8); //place first four, (second param is size)
for (int i = 4; i < 8; i++)
this->tableauPiles[i] = TableauPileT(tabls[i],7); //place second four
for (int i = 0; i < 4;i++)
this->foundationPiles[i] = FoundationPileT(); //just intialize
//FOR testing
for (int j = 0; j < 13; j++){
if (this->tableauPiles[4].cardAtIndex(j)){
std::cout << this->tableauPiles[4].getCardByIndex(j).getNum() << ",,,," << this->tableauPiles[4].getCardByIndex(j).getSuit() << std::endl;
}
}
//printed twice for assurance, both print as expected
for (int j = 0; j < 13; j++){
if (this->tableauPiles[4].cardAtIndex(j)){
std::cout << this->tableauPiles[4].getCardByIndex(j).getNum() << ",,-,," << this->tableauPiles[4].getCardByIndex(j).getSuit() << std::endl;
}
}
}
Heres where i then print the exact same thing again:
void Board::printTab(int i){
for (int j = 0; j < 13; j++){
if (this->tableauPiles[4].cardAtIndex(j)){
std::cout << this->tableauPiles[4].getCardByIndex(j).getNum() << ",,Third,," << this->tableauPiles[4].getCardByIndex(j).getSuit() << std::endl;
}
}
}
The header for the board
#ifndef BOARD_H
#define BOARD_H
class Board{
private:
CardT freeCells[4];
bool freeCellsOpen[4] = {false,false,false,false};
FoundationPileT foundationPiles[4];
TableauPileT tableauPiles[8];
int cardPosition(CardNum n, CardSuit s);
int emptyFreeCell();
public:
Board();
void setUp();
void moveToFreeCell(CardNum n, CardSuit s);
void moveToTableau(CardNum n, CardSuit s, int tableau);
void moveToFoundation(CardNum n, CardSuit s);
void printBoard();
void printTab(int i);
};
#endif
And finally this is then the output im given
1,,,,1
12,,,,2
4,,,,0
4,,,,1
4,,,,2
5,,,,3
10,,,,0
1,,-,,1
12,,-,,2
4,,-,,0
4,,-,,1
4,,-,,2
5,,-,,3
10,,-,,0
1,,Third,,1
0,,Third,,1
0,,Third,,0
32545,,Third,,1284192187
0,,Third,,10
32767,,Third,,1922833024
0,,Third,,0
The printed values are stored as enum.
Clearly changed between print statements, very new to c++ but have c experience among others. Any help is greatly appreciated as im going out of my mind.
Also im printing the 4th pile, i believe the 0-3 pile all print correctly, just 4+ are getting messed.
Also of note, the large unexpected values are changing between executions, rest stay constant.
Your card tables (CardT tabls[8][13];) are declared on the stack on your Board::setUp() method.
You then store pointers to these in your TableauPileT objects.
This works fine for your debug code because they are still on the stack,
but at the time you call the printTab function they have been deallocated.
So you're just reading whatever is left over in memory at that point, meaning you're getting undefined behaviour.
2nd loop after shuffle: why do you multiply i by 8 while the pile is just 6 cards? Obviously going out of array bounds. Should be [j+4+i*6]. By the way, the first 4 piles are only 7 cards long and multiplication of i by 8 is wrong. In those table initiating loops, j should be less than 7 and 6 respectively instead of 8 and 7.

Crossover in genetic algorithm

The part where I get an error (more specifically, where I get a popup saying Debug error! Abort () has been called) is the part where I try to do a crossover.
for (int i = 0; i < number_of_variables; i++)
{
int gene1 = gene_selection(rng);
std::cout << gene1 << " ";
if (gene1 == 0)
{
std::cout << "test 0";
new_individuals[k].chromosomes[0].at(i) = individuals[father].chromosomes[0].at(i);
}
else if (gene1 == 1)
{
std::cout << "test 1";
new_individuals[k].chromosomes[0].at(i) = individuals[mother].chromosomes[0].at(i);
}
}
It gets far enough to display "test 0" or "test 1" but it won't actually assign the genes from the father/mother to the new_individual.
I've tried changing up the line where it assigns the old genes to the new individual, but regardless of what I try I can't get it working.
If anyone could show me where (or how) I'm messing up, I'd be very thankful :)
Edit: Stepping through the debugger, I get the following
http://prnt.sc/b0iprq
Unhandled exception at .... in LearnCPP.exe: Microsoft C++ exception: std::out_of_range at memory location .....
Another edit: Just to be clear, it's this exact line where the abort occurs:
new_individuals[k].chromosomes[0].at(i) = individuals[father].chromosomes[0].at(i);
I'm surprised you get "test0" or "test1", without a std::endl
Follow the story of new_individuals
You allocate and resize it with
std::vector<one_individual> new_individuals;
new_individuals.resize(population_size);
Next this resize(), you have a vector of population_size (5) one_individual elements where chromosomes are std::vector<std::vector<double>> of size 0.
Next you resize the chromosomes with
for (int i = 0; i < population_size; i++)
{
new_individuals[i].chromosomes.resize(number_of_variables);
}
At this point you have cromosomes of size number_of_variables (7) but what's the meaning of this?
It's mean than every cromosomes is an std::vector of seven std::vector<double> of size zero.
So, when you access
new_individuals[k].chromosomes[0].at(i)
with k == 1 (why 1 and not 0?) and i == 0, new_individual[1].chromosomes[0] exist but is of size 0, new_individuals[k].chromosomes[0].at(i) check the size of chromomoses[0] to see if at least 1, fail and cause an exception (std::out_of_range)
Your intention was to allocate every new_individuals[i].chromosomes[j]?
Or your intention was to write
new_individuals[k].chromosomes[0].push_back(individuals[father].chromosomes[0].at(i));
?
p.s.: sorry for my bad English.
--- EDIT---
If your intention is to reserve 7x7 chromosomes, one way can be
for (int i = 0; i < population_size; i++)
{
new_individuals[i].chromosomes.resize(number_of_variables);
for (int j = 0; j < population_size; j++)
new_individuals[i].chromosomes[j].resize(number_of_variables);
}
Even using push_back(), I suggest you to reserve space
for (int i = 0; i < population_size; i++)
{
new_individuals[i].chromosomes.resize(number_of_variables);
for (int j = 0; j < population_size; j++)
new_individuals[i].chromosomes[j].reserve(number_of_variables);
}

error in two-dimensional array code

I wrote a multiplication table like this:
#include <iostream>
#include <conio.h>
using namespace std;
int main(){
int table[9][9], i, j;
for (i = 0; i < 10; ++i){
for (j = 0; j < 10; ++j)
{
table[i][j] = (i + 1) * (j + 1);
cout << table[i][j] << "\t";
}
cout << endl;
}
_getch();
return 0;
}
And when I run it it gives me the right answer but when I press a key it throws this error:
run time check faliure #2-stack around the variable table was corrupted
But it doesn't throw that error when I change the code to this:
......
int main(){
**int table[10][10]**, i, j;
for (i = 0; i < 10; ++i){
......
If they both give the same answer then what's the difference??
You are overflowing your arrays, The max index in bounds is 8 (since the indices are zero based and you defined 9 cells as your dimensions size so 8 will be the last cell in each dimension) and your for loop can reach till 9 (including 9) which will cause an overflow.
The snippet int table[9] declares an array of size 9, that means valid indices are actually 0-8. But your loop iterates from 0 to 9. This causes a write into an invalid memory region (which doesn't belong to your array), therefore corrupting your stack.
Now you actually have a two dimensional array, but the problem remains the same.
You're going outside the array in your for loops. They should be:
for (i = 0; i < 9; ++i){
for (j = 0; j < 9; ++j)
The array indexes run from 0 to 8, but you were going up to 9 because your conditions were i < 10 and j < 10.
Arrays in C/C++ start with 0 index.
When you declare table[9][9] you reserve memory for 9x9 array with indexes 0..8, 0..8
but in for loop your upper index is 9 - it is out of array range
I guess you should declare table like you pointed:
int table[10][10];
You are accessing out of array's range element.
Your array is a 9x9 table but you are trying to access 10x10 table.
So either use i<9 and j<9 in your both loops or increase your array size to table[10][10].
Hope this might help.
Rule of thumb: in for loops, N in (i = 0; i < N; i++) clause should (almost always) be equal to the corresponding array's length. When you see either i <= N or i < N + 1, it's (most often) a sign of the dreaded off-by-one bug.

Noobish Array problems: Run-Time Check Failure #2 - Stack around the variable 'arr' was corrupted

I'll be pretty honest/upfront here- I'm both a noob to C++, to computer programming in general, and additionally, to this site as well. I'll just preface my question by saying that I did in fact look at other questions possibly related to my own, but it just felt like they were outside of my scope. With that said, here's my problem:
I get this error message:
"Run-Time Check Failure #2 - Stack around the variable 'arr' was corrupted."
Here's my code. It's just a basic little thing for some array practice. The function multiTable outputs a multiplication table:
#include <iostream>
#include <iomanip>
using namespace std;
void multiTable();
int main()
{
multiTable();
return 0;
}
//Prints a 9 by 9 multiplication table;
void multiTable()
{
const int row = 9, col = 9;
int arr[row][col];
for(int i = 1; i <= row; i++)
{
for(int j = 1; j <= col; j++)
{
arr[i][j] = j * i;
cout << setw(3);
cout << arr[i][j];
}
cout << endl;
}
}
I also want to mention that instead of the function call, had I just included all of the code contained within the function body in main, I don't get the run-time error. Why is it that when it's contained within a function, I get the runtime error, but when it's just in main, I don't get the error? And of course, what would I have to change in order for the function call to not produce the error?
Those are your problems: for(int i = 1; i <= row; i++) and for(int j = 1; j <= col; j++) array counting starts from 0. So your for loops should be like this (starting from 0 and omitting the = part from <=):
for(int i = 0; i < row; i++) and for(int j = 0; j < col; j++)