Getting a segfault. Why? - c++

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.

Related

How can I fix my code so I don't get a C6385 warning?

I'm having trouble with a C6385 warning in my code. I'm trying to see if two arrays will equal each other. The warning I keep getting is on the line where if(p[i] == inputGuess[j]). I have tried redoing these line but I keep getting the same warning. Does anyone know what I'm doing wrong. This is also my first time programming in C++.
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include "Game.h"
#include <iostream>
#include <iomanip>
using namespace std;
int* generateNumbers(int n, int m) {
// Intialize random number
srand(static_cast<unsigned int>(time(NULL)));
// Declare array size to generate random numbers based on what is between 1 to (m)
int* numbers = new int[n];
for (int i = 0; i < n; i++) {
numbers[i] = (rand() % m) +1;
cout << numbers[i]<< " " << endl;
}
return numbers;
}
void Game::guessingGame(int n, int m) {
int* p;
int sum = 0;
// Call the generateNumber function
generateNumbers(n, m);
// Declare array based on user guesses
inputGuess = new int[n];
p = generateNumbers(n,m);
for (int i = 0; i < n; i++) {
cin >> inputGuess[i];
}
// See if the user guesses and computers answers match up
for (int i = 0; i < n; i++) {
for (int j = 0; i < n; j++) {
if (p[i] == inputGuess[j]){ //Where I keep getting the C6385 Warning
sum++;
break;
}
}
}
}
The C6385 warning documentation states:
The readable extent of the buffer might be smaller than the index used
to read from it. Attempts to read data outside the valid range leads
to buffer overrun.
https://learn.microsoft.com/en-us/cpp/code-quality/c6385?view=msvc-160
Your second if statement compares i < n instead of j < n and since i is never modified inside it will run forever. This causes the warning since you’ll access memory out of bounds. Fix the comparison.

Initialize all elements in matrix with variable dimensions to zero

I'm trying to initialize an int matrix in C++, with user-inputted dimensions, with every element set to zero. I know there are some elegant ways to do that with a one-dimensional array so I was wondering if there are any similar ways to do it with a two-dimensional array without using for loops and iterating through every element.
I found a source that gave several different ways, including std::fill (I've modified the code so that the dimensions are read with cin):
#include <iostream>
using namespace std;
int main() {
int x;
cin >> x;
int matrix[x][x];
fill(*matrix, *matrix + x * 3, 0);
for (int i = 0; i < x; i++) {
for (int j = 0; j < 3; j++) {
cout << matrix[i][j] << " ";
}
cout << endl;
}
}
But why does this work, and why would the pointer to the matrix in the arguments for fill be necessary if it's not necessary for a one-dimensional array? That source said it was because matrixes in C++ are treated like one-dimensional arrays, which would make sense, but that is why I don't understand why the pointer is needed.
I don't know if this is relevant, but in case it can help, I've described my previous attempts below.
At first I thought I could initialize all elements to zero like in a one-dimensional array. For the matrix, this worked fine when the side lengths were not read with cin (i.e. when I declared the matrix as int matrix[3][3] = {{}}; as answered here) but when I tried getting the side lengths from cin I started getting errors.
This was my code:
#include <iostream>
using namespace std;
int main() {
int x;
cin >> x;
int matrix[x][x] = {{}};
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << matrix[i][j] << " ";
}
cout << endl;
}
}
And when I tried to compile it, it threw this error:
matrix_test.cpp:7:14: error: variable-sized object may not be initialized
int matrix[x][x] = {{}};
^
1 error generated.
Why you're getting the error
c-style arrays (such as int matrix[3][3]) must have size specified at the point you declare it. They can't vary in size in C++.
What you could do instead.
If you use std::vector, there's a really elegant way to do it:
#include <vector>
#include <iostream>
int main() {
using namespace std;
int x;
cin >> x;
auto matrix = vector<vector<int>>(x, vector<int>(x, 0));
// This is how we can print it
for(auto& row : matrix) {
for(auto& elem : row) {
cout << elem << ' ';
}
cout << '\n';
}
}
In C++17, you can shorten this even further:
auto matrix = vector(x, vector(x, 0));
What vector(number, thing) means is "Create a vector of number, where each element is thing".
The second dimension of two-dimension array must be a compile time constant, but in your code x is not.
Actually if you write a function with a two-dimension parameter, the second dimension must also be a compile time constant. That's because the array is stored linearly in the memory and the compiler must know the second dimension to calculate the offset correctly.

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

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.

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;
}
}