I was making a cpp program in which it takes two input from the user which determine the size of the 2d array and pass the values to the mat class constructor and dynamically create an array of the user's defined size. But, I don't know why it is not working and showing segmentation fault
#include<iostream>
using namespace std;
class mat{
int **a;
int r, c;
public:
mat(int row, int col){
r = row;
c = col;
for(int i = 0; i < r; i++){
*a = new int[r];
*a++;
}
}
void input(){
for(int i = 0; i < r; i++){
for(int j = 0; i < c; j++){
cin >> a[i][j];
}
}
}
void display(){
for(int i = 0; i < r; i++){
for(int j = 0; i < c; j++){
cout << a[i][j] << "\t";
}
cout << endl;
}
}
};
int main()
{
int r, c;
cout << "enter row :";
cin >> r;
cout << "enter column :";
cin >> c;
mat m(r, c);
m.input();
cout << "array \n";
m.display();
}
I can feel that the issue is with the for loop in the constructor or maybe I am doing it wrong.
The class contains several errors.
The variable a is never initialized. When we try to address the memory pointed to by a we get a segmentation fault. We can initialize it like this a = new int*[r]
We should not change where a point's to, so don't use a++. Otherwise a[i][j] will not refer to the i'th row and the j'th column. We would also want to release the memory at some point.
The inner loop for the columns for(int j = 0; i < c; j++) once entered will never terminate and will eventually produce a segmentation fault. We need to change i < c to j < c.
If we fix these errors, it looks like this:
class mat {
int** a;
int r, c;
public:
mat(int row, int col) {
r = row;
c = col;
a = new int*[r];
for (int i = 0; i < r; i++) {
a[i] = new int[c];
}
}
void input() {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
cin >> a[i][j];
}
}
}
void display() {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
cout << a[i][j] << "\t";
}
cout << endl;
}
}
};
Related
I am writing a matrix class where I need to perform some matrix calculations in the main program. I am not sure why the program is ending abruptly when user chooses a matrix of size more than 2x2 matrix. The std::cin works fine until two rows but program ends after the loop reaches third row. Only part of the code is shown below which is related to my question.
#include<iostream>
#include <vector>
#include <cassert>
using std::vector;
using namespace std;
class Matrix {
private:
int rows;
int cols;
int **vtr;
public:
Matrix(int m = 2, int n = 2)
{
rows = m;
cols = n;
vtr = new int*[m];
for (int i = 0; i < m; i++)
{
vtr[i] = new int [n];
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
vtr[i][j] = 0;
}
}
}
void read()
{
cout << "Enter the number of rows and columns of Matrix separated by a space: ";
cin >> rows >> cols;
Matrix a(rows, cols);
a.write();
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << "(" << i << "," << j << ") : ";
cin >>vtr[i][j];
}
}
}
void write()
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << vtr[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
}
};
int main()
{
Matrix A, B, C;
int row, column ;
cout << "For Matrix A" << endl;
A.read();
cout << "For Matrix B " << endl;
B.read();
cout << "For Matrix C" << endl;
C.read();
}
Since the 2D array, vtr is created when declaring the Matrix object, you can move the vtr creation after reading the console input like below.
Matrix(int m = 2, int n = 2)
{
/*rows = m;
cols = n;
vtr = new int*[m];
for (int i = 0; i < m; i++)
{
vtr[i] = new int [n];
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
vtr[i][j] = 0;
}
}*/
}
void read()
{
cout << "Enter the number of rows and columns of Matrix separated by a space: ";
cin >> rows >> cols;
vtr = new int*[rows];
for (int i = 0; i < rows; i++)
{
vtr[i] = new int [cols];
}
//Matrix a(rows, cols);
//write();
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << "(" << i << "," << j << ") : ";
cin >>vtr[i][j];
}
}
write(); //Prints the array
}
The three matrixs will be construct when you define Matrix A, B, C. So the matrix size is 2x2. When you call function cin to assign value to some position is not in 2x2 will not work.
This question already has answers here:
What is The Rule of Three?
(8 answers)
Closed 2 years ago.
I am trying to write a matrice class in c++ with a overloaded + operator that is a friend function for summing a matrix with a number, ie sum every element of the matrice with the number.
for example:-
2+ |1|2| = |3|4|
|2|1| |4|3|
main.cpp :-
#include <iostream>
using namespace std;
class matrice {
int** a;
int rows, columns, i, j;
public:
matrice() {}
matrice(matrice& A) { //copy constructor for deep copying the result of 2+A into C
rows = A.rows;
columns = A.columns;
a = new int* [rows];
for (i = 0; i < rows; i++) {
a[i] = new int[columns];
*a[i] = 0;
}
for (i = 0; i < rows; i++) {
for (j = 0; j < columns; j++) {
a[i][j] = A.a[i][j];
}
}
}
matrice(int m, int n) {
rows = m;
columns = n;
a = new int* [rows];
for (i = 0; i < rows; i++) {
a[i] = new int[columns];
*a[i] = 0;
}
}
~matrice() {
delete[] a;
}
void insert(int p, int q, int value) {
a[p][q] = value;
}
void print() {
for (i = 0; i < rows; i++) {
cout << "\n";
for (j = 0; j < columns; j++) {
cout << a[i][j] << " ";
}
}
}
friend matrice operator+(int k, matrice& A);
friend matrice operator+(matrice& A, int k);
};
matrice operator+(int k, matrice& A) { //for performing 2+A
matrice temp(A.rows, A.columns);
for (int i = 0; i < A.rows; i++) {
for (int j = 0; j < A.columns; j++) {
temp.a[i][j] = A.a[i][j] + k;
}
}
return temp;
}
matrice operator+(matrice& A, int k) { //for performing A+2
matrice temp(A.rows, A.columns);
for (int i = 0; i < A.rows; i++) {
for (int j = 0; j < A.columns; j++) {
temp.a[i][j] = A.a[i][j] + k;
}
}
return temp;
}
int main() {
int i, j, m, n, value;
cout << "\nEnter order of A matrice:";
cin >> m >> n;
matrice A(m, n);
cout << "\nEnter the matrice:";
for (i = 0; i < m; i++) {
cout << "\nEnter row " << i + 1 << " : ";
for (j = 0; j < n; j++) {
cin >> value;
A.insert(i, j, value);
}
}
cout << "\nThe entered matrice is :";
A.print();
cout << "\n\n";
cout << "\nEnter order of B matrice:";
cin >> m >> n;
matrice B(m, n);
cout << "\nEnter the matrice:";
for (i = 0; i < m; i++) {
cout << "\nEnter row " << i + 1 << " : ";
for (j = 0; j < n; j++) {
cin >> value;
B.insert(i, j, value);
}
}
cout << "\nThe entered matrice is :";
B.print();
cout << "\n\ntesting 2+A";
matrice C; //Everything upto here is fine
C = A + 2; // C.a is pointing to unreadable memory because of destruction after doing A+2
C.print(); // so access violation error
}
The problem is that the destructor of C is called after invoking the copy constructor which causes the double pointer a in C to be deleted. So when C.print() is called An Access violation reading location 0xDDDDDDDD exception is thrown.
I can't find out why C's destructor is called.
The rule of 5 says that if you manually handle allocations, you should have an explicit (or explicitely deleted):
copy constructor
copy assignment operator
move constructor
move assignement operator
destructor
You might omit the ones that you are sure that you code will never use, but it is highly dangerous.
Anyway correct allocation/de-allocation handling is complex and requires very cautious code. For example the correct declaration for a copy ctor should be matrice(const matrice& A), and comments already warned you of memory leaks.
So my advice is:
if you want to learn about manual allocation management, follow best practices: rule of 5 an copy/swap idiom to avoid caveats
if you just want working code, replace 1D dynamic arrays with vectors and let the standard library handle the corner cases
I'm compiling this on linux. It will compile and run, but when I enter values for n and p, this is what my terminal looks like:
7
1.0
Segmentation fault (core dumped)
In this case, 7 is the input for n, and 1.0 is the input for p. I've tried this with different values. The idea is to use Dynamic Programming to fill in a 2D array of probabilities through recursion. Let me know if you need more info, but this is the entirety of the code.
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int n;
double p;
cin >> n;
cin >> p;
cout << n;
cout << p;
cout << "Initializing array.";
double** probability = new double*[n];
for(int i = 0; i < n; ++i)
{
probability[i] = new double[n];
}
//cout << "Beginning filling i loop.";
for(int i = 0; i < n; i++)
{
probability[i][0] = 0;
}
//cout << "Beginning filling j loop.";
for(int j = 0; j < n; j++)
{
probability[0][j] = 1;
}
//cout << "Beginning filling nested loop.";
for(int i = 1; i< n; i++)
{
for(int j = 1; j< n; j++)
{
probability[i][j] = (p * probability[i-1][j]) + ((1-p) * probability[i][j-1]);
}
}
cout << "Probability: ";
cout << probability[n][n];
//cleanup
for(int i = 0; i < n; ++i)
{
delete probability[i] ;
}
delete probability;
return 0;
}
cout << probability[n][n];
probability[][] is an n by n array. The last element is probability[n-1][n-1] , so you are running off the end of the array and invoking undefined behavior.
I have to create a program that allows a user to fill in a (partial) Latin Square of order 4. You can use 0's to represent empty cells. The user will give the number to place, the row and column. The number should only be placed if it does not violate the properties of a partial Latin square and it shouldn't rewrite numbers that have already been placed.
I have an matrix that is outputting all zeroes now. So next I have to replace each of these values by what the user is inputting. The problem is I don't know how to do this.
Here is my code:
#include <iostream>
using namespace std;
const int ORDER = 4;
void fill (int m[], int order);
void outputMatrix (int m[], int order);
void replaceValue (int m[], int order, int n, int row, int column);
int main(){
int matrix[ORDER];
int row;
int column;
int n;
fill (matrix, ORDER);
outputMatrix (matrix, ORDER);
do {
cout << "Enter the number to place, the row and the column, each seperated by a space: ";
cin >> n;
cin >> row;
cin >> column;
}while (n > 0 || n <= ORDER);
if (n <= 0 || n >= ORDER){
cout << "Thank you";
cout << endl;
}
return 0;
}
void fill (int m[], int order){
for (int i = 0; i < order*order; i++){
m[i] = 0;
}
}
void outputMatrix (int m[], int order){
int c = 0;
for (int i = 0; i < order*order; i++){
c++;
cout << m[i] << ' ';
if (c == order){
cout << endl;
c = 0;
}
}
cout << endl;
}
void replaceValue (int m[], int order, int n, int row, int column){
for (int i = 0; i < order; i++){
m[order] = m[row][column];
m[row][column] = n;
}
}
How do I replace values in a Matrix in C++?
If you have a matrix, matrix[row][col] = value; would do the trick. However, I see that you allocate a single array. Make sure you look at this.
EDIT:
I looked closer at you code and you are doing some things wrong.
First:
matrix[ORDER]
will create a single array of ORDER values. If you want and ORDER by ORDER matrix try:
matrix[ORDER][ORDER]
Second:
You are calling:
void fill (int m[], int order){
for (int i = 0; i < order*order; i++){
m[i] = 0;
}
}
with an of size 4 and order == 4. This will loop outside the array and give you problems.
Try something like:
matrix[ORDER][ORDER];
for (int row = 0; row != ORDER; ++row)
{
for (int col = 0; col != ORDER; ++col)
{
matrix[row][col] = 0;
}
}
Hope this helps.
You can't really write arr[i][j] if arr is defined as arr[]. There's no information about the length of the row (how many columns there are).
You could use arrays of type arr[][4], and write your functions like so:
// The & is to pass by reference.
void print(int (&arr)[][4], int length)
{
for(int i = 0; i < length; i++) {
for(int j = 0; j < 4; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
But in my opinion for a low-order multidimensional array like this one, using a typedef for a vector of vectors is the better option:
typedef vector<vector<int> > Matrix;
void print(Matrix& arr)
{
for(int i = 0; i < arr.size(); i++) {
for(int j = 0; j < arr[i].size(); j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
In either case, writing arr[i][j] = k will behave as you expect.
The easiest way to clear/zero your matrix is that:
memset( &matrix, 0, sizeof(matrix));
;-)
I'm trying to create a 3D char array with dynamic memory. I create the char*** point in main then pass it to input and everything works fine until the input function returns and i try to repring the same locaton from main. I get "Access violation reading location." Any suggestions?
void input(char ***a, int f, int n)
{
cin >> f;
cin >> n;
a = new char**[f];
for (int i =0; i <f; ++i)
{
a[i]= new char*[n];
for (int j=0; j <n; ++j)
{
a[i][j] = new char[n];
}
}
for (int i =0; i<f; ++i)
{
for (int j=0; j<n; ++j)
{
for (int k = 0; k <n ;++k)
{
a[i][j][k] = '.';
cout << a[i][j][k];}
}
}
cout <<endl << endl<< a[2][5][5]; //test to see is value is '."
}
int main()
{
char ***station = 0;
int floors=0, n=0;
input(station, floors, n);
cout << endl << endl << station[2][5][5];
}