How to debug why the compiler crashes on my C++ program? - c++

Code 1: supposed to take a matrix (m by n) size and then find the min value in each row. Doesn't show any errors, runs but the black screen (devc++) for the compiler simply crashes without doing anything and has a ridiculously high return value (3221225725 to be exact).
I'm not sure how to fix or improve it, also it works when the size of the matrix is constant, like instead of cin to get size a simple number makes it work. I am not sure why; I'm new to programming.
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
int m,n;
int B[m][n];
int A[m+1][n+1] = {0};
cin>>m;
cin>>n;
for (int x = 0; x < m; ++x)
{
for (int y = 0; y < n; ++y)
{
cout<< "Enter in value for row " << x << ", column " << y << ".\n";
cin>> A[x][y];
}
}
cout << "Input:" <<endl;
for (int x = 0; x < m; ++x)
{
for (int y = 0; y < n; ++y)
{
cout<< A[x][y] << "\t";
}
cout << "\n";
}
for (int x = 0; x < m; ++x)
{
for (int y = 0; y < n; ++y)
{
A[x][4] = A[x][1];
if (A[x][4] > A[x][y])
A[x][4] = A[x][y];
}
}
cout <<"Output:"<<endl;
for (int x = 0; x < m+1; ++x)
{
for (int y = 0; y < n+1; ++y)
{
cout << A[x][y] << "\t";
}
cout<<"\n";
}
getchar ();
return 0;
}
And this is code 2:
#include <iostream>
#include <math.h>
using namespace std;
int main ()
{
int i,j,R,C,Too;
double a[i][j];
float f;
Too=0;
cin>>R;
cin>>C;
for (int i=0; i<R; i++)
for (int j=0; j<C; j++)
{
f=i+j/2;
a[i][j]=sin(f);
if (a[i][j]>0)
{
Too=Too+1;
}
cout << "a[" << i << "][" << j << "]: ";
cout << a[i][j]<< endl;
}
cout<<Too<<" Shirheg eyreg element bn"<<endl;
}
the elements in this matrix is generated by the formula f=i+j/2; a[i][j]=sin(f);
and simply outputs how many positive elements are there. for some odd reason the elements are always double like the output is something like:
0
0
0.841471
0.841471
and one other number then gets getting double and then a number and then double.
how to fix?

Strange return values and crashes when working in C++ are often a sign of uninitialized values. For example, consider the following:
int main() {
int m,n; // <-- declare 'm' and 'n', but we don't initialize them to have a value
int B[m][n]; // <-- use the values in 'm' and 'n' to allocate memory for 'B'
...
cin >> m; // <-- only now are you setting m to a value, but you already used it.
cin >> n; // <-- same thing with n.
...
}
The above code is wrong because it uses the variables identified by 'm' and 'n' before it sets them to have a particular value, so until you set their value (with cin) they just have whatever value happened to be sitting in memory at the time they were created.
Assigning a value to them is called "initialization" or initializing them the first time you do it. Before that they just hold that value from memory.
Ultimately, each line of code is using some variables and may be making assignments to other variables. So make sure each variable that is being used has already been initialized before you reach that line of code.
You will have to debug your own code in order to learn effectively, and the above example is not the only error or issue here, but a few basic tips to help you along the way:
Always look out for anything using uninitialized values like m and n
If it makes sense, initialize values as soon as they are created
i and j and k as variable names are usually declared only in a loop, because you usually only need them to exist inside the loop.
If you declare int i in a function, you should not declare int i in a loop within that function. The two i's now mean different things, which is confusing.
put spaces around your << and >> operators. It will make the code easier to read.
If you're having trouble, try printing out the value of a variable with cout and see if it makes sense. If not, there is a problem before that point in the program.
If you're having trouble, try working on one section of the code at a time until it behaves the way you expect.

Related

Convert userInput (string) to UserInput(int) mid for loop

I am working on a program that has to do with arrays. I decided that the input the user provides to be a string to later being converted to an integer once it is determined it is one. This way the program wouldn't run into an error when words/letters are entered. The issue I am having is the conversion from string to int. I want to change that because later in the program I am going to search the array for a given value and display it and its placement in the array. This is the code I have thus far:
#include <stdio.h>
#include <iostream>
using namespace std;
//check if number or string
bool check_number(string str) {
for (int i = 0; i < str.length(); i++)
if (isdigit(str[i]) == false)
return false;
return true;
}
int main()
{
const int size = 9 ;
int x, UserInput[size], findMe;
string userInput[size];
cout << "Enter "<< size <<" numbers: ";
for (int x =0; x < size; x++)
{
cin >> userInput[x];
if (check_number(userInput[x]))
{//the string is an int
}
else
{//the string is not an int
cout<<userInput[x]<< " is a string." << "Please enter a number: ";
cin >> userInput[x];}
}
int i;
for (int i =0; i < size; i++)
{
int UserInput[x] = std::stoi(userInput[x]); // error occurs here
}
for (int x= 0; x< size; x++)
{
if (UserInput = findMe)
{
cout <<"The number "<< UserInput[x] << "was found at " << x << "\n";
}
else
{
//want code to continue if the number the user is looking for isn't what is found
}
}
return 0;
}
Made comments here and there to kinda layout what I want the code to do and whatnot. I apperciate any help you can give, thank you.
This code:
int UserInput[x] = std::stoi(userInput[x]);
declares an int array of size x, to which you are assigning a single int (the result of std::stoi), which obviously doesn't work.
You need to assign an int to a particular index of the existing array, like this:
UserInput[x] = std::stoi(userInput[x]);
Given this comparison if (UserInput = findMe), which should actually be if (UserInput == findMe), it seems you want to declare a single int which stores the result of std::stoi. In that case, you should use a different name than the array, and write something like this:
int SingleUserInput = std::stoi(userInput[x]);
Also, please indent your code consistently, and compile with all your warnings turned on. Your code will be easier to read, and the compiler will point out additional problems with your code. And please don't use using namespace std;, it's a bad habit.
I don't understand why do u even need to use another loop to convert the string value to int. stdio.h header file does provides with preinstalled functions to make your work easier...
for (int x =0; x < size; x++)
{
getline(cin,userInput1[x]);
UserInput[x]=stoi(userInput1[x]);
}
stoi() function converts the string input to int, and you can call it dynamically as soon as you enter your string input,It will make you work easier and reduce the time complexity

Some test cases aren't passing

#include <iostream>
#include <vector>
int i=0; //points at the current stack that we are working with
int box=0; //no. of boxes held by the crane
int64_t H; //max. height of the stacks given in the que.
int main()
{
int n, value; //storing no. of stacks and creating an additional variable value to store operations
std::cin>> n >> H;
int64_t arr[n]; //storing the no. of boxes each stack has in an array
std::vector<int> arr2; //storing the operations we have to perform in a vector
for(int j=0; j<n; j++){std::cin>> arr[j];} //getting arr
while(std::cin>>value) //getting arr2
{
arr2.push_back(value);
}
for(int xy=0; xy<n; xy++){if(arr[xy]>H){return 0;}} //ensuring that all stacks have no.of boxes less than max. height
if(arr2.size()<1 || arr2.size()>10e5 || n<1 || n>10e5 || H<1 || H>10e8){return 0;} //constraints given in the que.
int k=0; //creating a variable to keep count of how many programs we have already executed
while(k<arr2.size()){
if(arr2[k] == 1){MoveLeft();}
else if(arr2[k]==2){MoveRight(n);}
else if(arr2[k]==3){PickBox(arr, i);}
else if(arr2[k]==4){Dropbox(arr, i);}
else if(arr2[k]==0){k=arr2.size();}
k++;
}
for(int j=0; j<n; j++){std::cout<< arr[j] << " ";} //printing the arr after executing the code
return 0;
}
This is a question from a past year ZCO. And the above code is what I wrote to solve the prob.
The four functions Moveleft, MoveRight, Pickbox, Dropbox have been defined in the same file but aren't shown here because I think there's no issue with them.
When I submit the code, all test cases passed except 2. I don't know what is the problem with my code. Pls help me.
I have tried my best to make the code readable. Sorry if the code looks messy.
With the method you're trying to define an array with a user-input length is unfortunately invalid in C++.
But fortunately, there are basically two methods use to allocate arrays dynamically.
Method 1: Using Vectors
Vector is an important part of C++. It has a lot of features (e.g. its size don't need to be defined static unlike a normal array does, can redefine array size, etc.) An example's given:
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> vArray; // vector<> declaration
int size = 0;
int getInput = 0;
std::cout << "Enter an array size: ";
std::cin >> size;
for (int i = 0; i < size; i++) {
std::cout << "Enter a value: ";
std::cin >> getInput;
vArray.push_back(getInput); // inserts one+ container and data in it
}
for (int i = 0; i < vArray.size(); i++) {
// retrieving contained data...
std::cout << vArray[i] << std::endl;
}
return 0;
}
Method 2: Using 'new' Keyword with Pointed Variable
The simple use of new will help you to achieve your requirement. It's less recommended since already there's concept of vectors which actually works efficiently than arrays. Let's take a look into a simple program:
#include <iostream>
int main(void) {
int *pArray;
int size;
std::cout << "Enter an array size: ";
std::cin >> size;
pArray = new int[size]; // initializing array with dynamic size
for (int i = 0; i < size; i++) {
std::cout << "Enter value: ";
std::cin >> pArray[i];
}
for (int i = 0; i < size; i++) {
std::cout << pArray[i] << std::endl;
}
delete[] pArray;
return 0;
}
Both are nice options to work with, but it's recommended by most using vector<>.

Getting a segfault. Why?

I keep getting a segfault on grid[x][y] = rand();
Any help? I've tried replacing the random function call with a number to see if thats what was causing the problem but it doesnt seem so.. I've got no idea
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
int x;
int y;
int gridMult;
int grid[gridMult][gridMult];
srand(time(NULL));
std::cout << "Enter grid size:: ";
std::cin >> gridMult;
while(x < gridMult){
while(y < gridMult){
grid[x][y] = rand();
y++;
}
x++;
}
for(int x = 0; x < gridMult; x++){
for(int y = 0; y < gridMult; y++){
std::cout << grid[x][y];
}
std::cout << std::endl;
}
return 0;
}
In those two lines
int gridMult;
int grid[gridMult][gridMult];
gridMult is undefined, so how do you expect the compiler to properly size up your array?
Then when you get to the loops:
while(x < gridMult){
while(y < gridMult){
grid[x][y] = rand();
x and y are also undefined.
In general, I'd change those loops to for (or range-for) to scope the iteration variables as narrowly as possible.
If you want it to allocate dynamically based on user input, use std::vector and resize it to the desired size.
I'd also add that 2-dimensional arrays are typically realized on a 1-dimensional storage vector and 2-dimensional view on top of it, instead of nested vectors, so you might want to read about those patterns.

Weird Array Stuff (Array indexes getting values without me setting it)

I am trying to write a sudoku solver.
I got the input almost done, but something strange started happening. On the index [i][9] of int sudoku[i][9], there are numbers present that I have never put there.
For example, when I run the code below with the input that is commented below using namespace std;, the output is:
410270805
085146097
070580040
927451386
538697412
164328759
852704900
090802574
740965028
Of course, I only need 0 through 8, but I was wondering what is causing integers to appear at the 9th index.
This is the code:
#include <iostream>
#include <math.h>
#include <cstdlib>
using namespace std;
/*
410270805
085146097
070580040
927451386
538697412
164328759
852704900
090802574
740965028
*/
int main()
{
int sudoku[9][9];
int solving[9][9][9];
int input;
for (int i=0; i<=8; i++) {
cin >> input;
int j;
int k;
for (j=8, k=1; j>=0; j--, k++) {
int asdf = input/pow(10,k-1);
sudoku[i][j] = asdf % 10;
}
}
cout << endl;
for (int i=0; i<=8; i++) {
for (int j=0; j<=9; j++) {
cout << sudoku[i][j];
}
cout << endl;
}
return 0;
}
Accessing elements outside of the defined region of an array is Undefined Behavior (UB).
That means it could:
Allow you to access uninitialized space (what yours is doing hence the random numbers)
Segfault
Any number of other random things.
Basically don't do it.
In fact stop yourself from being able to do it. Replace those arrays with std::vectors and use the .at() call.
for example:
std::vector<std::vector<int>> sudoku(9, std::vector<int>(9, 0));
for (int i=0; i<=8; i++) {
for (int j=0; j<=9; j++) {
cout << sudoku.at(i).at(j);
}
cout << endl;
}
Then you will get a thrown runtime exception that explains your problem instead of random integers or segfaults.
I think I found your problem, at your very last for loop you used j <= 9 instead of j <= 8. You then tried to write (j) leaving the possibility of it writing 9 wide open. Try replacing that 9 with 8.

c++ error: invalid types 'int[int]' for array subscript

Trying to learn C++ and working through a simple exercise on arrays.
Basically, I've created a multidimensional array and I want to create a function that prints out the values.
The commented for-loop within Main() works fine, but when I try to turn that for-loop into a function, it doesn't work and for the life of me, I cannot see why.
#include <iostream>
using namespace std;
void printArray(int theArray[], int numberOfRows, int numberOfColumns);
int main()
{
int sally[2][3] = {{2,3,4},{8,9,10}};
printArray(sally,2,3);
// for(int rows = 0; rows < 2; rows++){
// for(int columns = 0; columns < 3; columns++){
// cout << sally[rows][columns] << " ";
// }
// cout << endl;
// }
}
void printArray(int theArray[], int numberOfRows, int numberOfColumns){
for(int x = 0; x < numberOfRows; x++){
for(int y = 0; y < numberOfColumns; y++){
cout << theArray[x][y] << " ";
}
cout << endl;
}
}
C++ inherits its syntax from C, and tries hard to maintain backward compatibility where the syntax matches. So passing arrays works just like C: the length information is lost.
However, C++ does provide a way to automatically pass the length information, using a reference (no backward compatibility concerns, C has no references):
template<int numberOfRows, int numberOfColumns>
void printArray(int (&theArray)[numberOfRows][numberOfColumns])
{
for(int x = 0; x < numberOfRows; x++){
for(int y = 0; y < numberOfColumns; y++){
cout << theArray[x][y] << " ";
}
cout << endl;
}
}
Demonstration: http://ideone.com/MrYKz
Here's a variation that avoids the complicated array reference syntax: http://ideone.com/GVkxk
If the size is dynamic, you can't use either template version. You just need to know that C and C++ store array content in row-major order.
Code which works with variable size: http://ideone.com/kjHiR
Since theArray is multidimensional, you should specify the bounds of all its dimensions in the function prototype (except the first one):
void printArray(int theArray[][3], int numberOfRows, int numberOfColumns);
I'm aware of the date of this post, but just for completeness and perhaps for future reference, the following is another solution. Although C++ offers many standard-library facilities (see std::vector or std::array) that makes programmer life easier in cases like this compared to the built-in array intrinsic low-level concepts, if you need anyway to call your printArray like so:
printArray(sally, 2, 3);
you may redefine the function this way:
void printArray(int* theArray, int numberOfRows, int numberOfColumns){
for(int x = 0; x < numberOfRows; x++){
for(int y = 0; y < numberOfColumns; y++){
cout << theArray[x * numberOfColumns + y] << " ";
}
cout << endl;
}
}
In particular, note the first argument and the subscript operation:
the function takes a pointer, so you pass the name of the multidimensional array which also is the address to its first element.
within the subscript operation (theArray[x * numberOfColumns + y]) we access the sequential element thinking about the multidimensional array as an unique row array.
If you pass array as argument you must specify the size of dimensions except for the first dim. Compiler needs those to calculate the offset of each element in the array. Say you may let printArray like
void printArray(int theArray[][3], int numberOfRows, int numberOfColumns){
for(int x = 0; x < numberOfRows; x++){
for(int y = 0; y < numberOfColumns; y++){
cout << theArray[x][y] << " ";
}
cout << endl;
}
}