Gauss Elimination C++ segmentation fault - c++

I'm really stuck with my code for Gauss Elimination in C++, I need to return upper triangular matrix but still only thing I get is Segmentation fault. I know there must be some sort of going of allocated memory but I can't find where.
Code:
#include <iostream>
using namespace std;
double ** allocateDynamicArray(int order){
double ** dynArray = new double *[order];
int cols = order+1;
double *pool = new double [order * cols];
for(int i = 0;i < order; i++, pool += cols){
dynArray[i] = pool;
}
return dynArray;
}
void deallocateDynamicArray(double **dynArray){
delete [] dynArray[0];
delete [] dynArray;
}
void addAndPrintArray(double **dynArray, int order){
cout << "Zadejte prvky pole radu " << order << endl;
for(int i=0; i< order; i++){
for(int j=0; j< order+1; j++){
cout << "Pole[" << i << "][" << j << "]: ";
cin >> dynArray[i][j];
}
}
for(int i=0; i< order; i++){
for(int j=0; j< order+1; j++){
if(dynArray[i][j] < 10 && dynArray[i][j] >= 0){
cout << " ";
}
cout << dynArray[i][j] << " ";
}
cout << endl;
}
}
double ** gaussElimination(double** dynArray, int order){
for(int j=1; j<=order; j++) /*Horni trojuhelnikova matice*/
{
for(int i=1; i<=order; i++)
{
if(i>j)
{
double c=dynArray[i][j]/dynArray[j][j];
for(int k=1; k<=order+1; k++)
{
dynArray[i][k] = dynArray[i][k] - c * dynArray[j][k];
}
}
}
}
return dynArray;
}
int main()
{
cout << "Zadejte rad matice: ";
int order;
cin >> order;
double **arr = allocateDynamicArray(order);
addAndPrintArray(arr, order);
gaussElimination(arr, order);
deallocateDynamicArray(arr);
return 0;
}
Can anyone tell me what's wrong?

The problem is that in C/C++ the first element of an array should have index 0, so your
for(int i=1; i<=order; i++)
should be
for(int i=0; i<order; i++)
in the gaussElimination function.

Related

MAX value of matrix and saving indexes in the same loop

I get a NxM sized matrix and I have to find the max value, the number of max values and the lines that contain it.
I tired using three for{for{}} loops, but it took too long. This method seems to work for small inputs, but when I try it with a 1000x1000 matrix, it finishes before it even takes all the input.
I realise this may be too much of a noob question, but I couldn't find anything else.
Here's my code:
#include <iostream>
using namespace std;
int main()
{
int n, m;
int crnt{-51}, cnt{0};
cin >> n >> m;
int vekt[m];
int lines[n];
int inp;
for(int i=0; i<n; i++)
{
for(int p=0; p<m; p++)
{
cin >> vekt[p];
}
for(int j=0; j<m; j++)
{
if(vekt[j] == crnt)
{
lines[cnt] = i + 1;
cnt += 1;
}
if(vekt[j] > crnt)
{
crnt = vekt[j];
lines[0] = i + 1;
cnt = 1;
}
}
}
cout << cnt;
for(int i=0; i<cnt; i++)
{
cout << " " << lines[i];
}
return 0;
}
EDIT : not using vector or [n] was just easier... I simply saved it to a variable and used a bool:
int main()
{
int n, m;
int crnt{-51}, cnt{0};
cin >> n >> m;
int vekt[m];
int lines[n];
int inp;
bool inLine;
inLine = false;
for(int i=0; i<n; i++)
{
inLine = false;
for(int j=0; j<m; j++)
{
cin >> inp;
if(inp == crnt && inLine == false)
{
lines[cnt] = i + 1;
cnt += 1;
inLine = true;
}
if(inp > crnt)
{
crnt = inp;
lines[0] = i + 1;
cnt = 1;
}
}
}
cout << cnt;
for(int i=0; i<cnt; i++)
{
cout << " " << lines[i];
}
return 0;
}
This cut the time by enough so that I went under the limit.
int vekt[m]; is not standard C++, it is a variable length array (which some compilers allow as extension). Use std::vector instead.
That would also fix the bug you currently have: If cnt >= n (i.e. if you find more maxima than the matrix has lines), you will go out of bounds of lines and your program will most likely crash (although anything could happen), which is more likely to happen with larger matrices.
You can do this instead:
Declaration and initialization:
std::vector<int> linesWithMaxima;
When you find another value equal to the current maximum:
linesWithMaxima.push_back(i+1);
When you find a new maximum (larger than current):
linesWithMaxima.clear();
linesWithMaxima.push_back(i+1);
Note that this will list a line with multiple (identical) maxima multiple times. If you want to avoid duplicates, you can either check that you have not already added the current line (linesWithMaxima.back() != i+1) or use std::sort, std::unique and std::vector::erase.
Other than that your code looks fine. I would recommend naming the loop indices better (line instead of i etc.) and possibly merging the p and j loop because separating them seems to have no purpose. And if you want the most negative integer, use std::numeric_limits<int>::lowest().
Check this realization, without STL and vectors:
void input_matrix(int **&matrix, int &lines, int &columns)
{
int m = 0, n = 0;
cout << "input lines count:";
cin >> m;
cout << "input rows count:";
cin >> n;
matrix = new int *[m];
for(int i = 0;i < m;i++)
matrix[i] = new int[n];
cout << endl << "input matrix:" << endl;
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
cin >> matrix[i][j];
lines = m;
columns = n;
}
void print_matrix(int **&matrix, int &lines, int &columns)
{
for(int i = 0; i < lines; i++)
{
for(int j = 0; j < columns; j++)
cout << matrix[i][j] << " ";
cout << endl;
}
}
int find_max(int **matrix, int lines, int columns, int &max_count)
{
int max = INT_MIN;
max_count = 0;
for(int i = 0; i < lines; i++)
for(int j = 0; j < columns; j++)
{
if(matrix[i][j] > max)
{
max = matrix[i][j];
max_count = 1;
}
else
if(matrix[i][j] == max)
++max_count;
}
return max;
}
int main()
{
int **matrix = nullptr;
int m=0, n=0, count=0;
input_matrix(matrix, n, m);
cout << endl;
print_matrix(matrix, n, m);
cout << endl;
int max = find_max(matrix, n, m, count);
cout << "max=" << max << " count=" << count << endl;
for(int i = 0; i < n; i++)
delete[]matrix[i];
delete []matrix;
}
As requested by mister Max Langhof I would also like to propose a more modern solution, based on the std::vector container, which does not need pointers and manual memory management. It's a simple class matrix:
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdint>
using namespace std;
class matrix
{
private:
vector<vector<int>> m_data;
public:
matrix(int cols, int rows)
{
m_data.resize(cols);
for(auto &r : m_data)
r.resize(rows);
}
int max_element()
{
int max = INT_MIN;
for(auto &row: m_data)
{
auto maxinrow = *std::max_element(row.begin(), row.end());
if(maxinrow > max)
max = maxinrow;
}
return max;
}
int element_count(int elem)
{
int count = 0;
for(auto &row : m_data)
count += std::count_if(row.begin(), row.end(), [elem](int a){return a == elem;});
return count;
}
friend istream& operator>>(istream &os, matrix &matr);
friend ostream& operator<<(ostream &os, matrix &matr);
};
Input and output operators could be realized like this:
istream& operator>>(istream &os, matrix &matr)
{
for(int i = 0; i < matr.m_data.size(); i++)
{
for(int j = 0; j < matr.m_data[i].size(); j++)
cin >> matr.m_data[i][j];
cout << endl;
}
return os;
}
ostream& operator<<(ostream &os, matrix &matr)
{
for(int i = 0; i < matr.m_data.size(); i++)
{
for(int j = 0; j < matr.m_data[i].size(); j++)
cout << matr.m_data[i][j] << " ";
cout << endl;
}
return os;
}
And a sample of using of this matrix:
int main()
{
int m = 5, n = 4;
matrix matr(m, n);
cout << "input matrix:" << endl;
cin >> matr;
cout << endl << matr;
int max = matr.max_element();
cout << "max: " << max << " count:" << matr.element_count(max) << endl;
}
Checkout something like this
#include <iostream>
#include <set>
#include <vector>
int main() {
int rowsNo, columnsNo;
std::cin >> rowsNo >> columnsNo;
std::vector<int> matrix(rowsNo*columnsNo);
//Creating matrix
for(auto row = 0; row < rowsNo; ++row) {
for (auto column = 0; column < columnsNo; ++column)
std::cin >> matrix[row*columnsNo + column];
}
auto maxValue = -51;
//Finding positions of maximums
std::set<int> linesWithMaxValue;
for (auto position = 0; position < matrix.size(); ++position) {
if(matrix[position] == maxValue)
linesWithMaxValue.insert(position / columnsNo);
else if(matrix[position] > maxValue) {
linesWithMaxValue.clear();
maxValue = matrix[position];
linesWithMaxValue.insert(position / columnsNo);
}
}
//Print info
const auto numberOfMaxValues = linesWithMaxValue.size();
std::cout << "Number of maxiums: " << numberOfMaxValues << std::endl;
std::cout << "Lines that contains maximum:";
for (const auto& lineId : linesWithMaxValue)
std::cout << " " << lineId;
return 0;
}

How to read matrix and sum them up?

I wanted to do a coding where it reads a 4x4 matrices and sum them up. I dont know where I did wrong. My result is it keeps on asking to enter the elements. I just wanted a 4x4. Can anyone help me?
#include <iostream>
using namespace std;
const int SIZE = 4;
double sumColumn(const double m[][SIZE], int rowSize, int columnIndex)
{
int sum = 0;
for (int i = 0; i<SIZE; i++)
{
for (int j = 0; j<SIZE; j++)
{
sum = sum + m[i][j];
}
}
return sum;
}
int main()
{
double m[SIZE][SIZE], sum = 0;
cout << "Enter the elements of the matrix" << endl;
for (int i = 0; i<SIZE; i++)
for (int j = 0; j<SIZE; j++)
cin >> m[i][j];
sum = sumColumn(m, SIZE, SIZE);
cout << sum << endl;
return 0;
}
A good practice is using curly braces even if the content of the "for" has one line, but in your case must be in the next way
for (int i = 0; i<SIZE; i++) {
for (int j = 0; j<SIZE; j++) {
cin >> m[i][j];
sum = sumColumn(m, SIZE, SIZE);
}
}
Greetings
The complete code is:
#include <iostream>
using namespace std;
const int SIZE = 4;
double sumColumn(const double m[][SIZE], int rowSize, int columnIndex)
{
int sum = 0;
for (int i = 0; i<SIZE; i++)
{
for (int j = 0; j<SIZE; j++)
{
sum = sum + m[i][j];
}
}
return sum;
}
int main()
{
double m[SIZE][SIZE], sum = 0;
cout << "Enter the elements of the matrix" << endl;
for (int i = 0; i<SIZE; i++)
{
for (int j = 0; j<SIZE; j++)
{
cin >> m[i][j];
sum = sumColumn(m, SIZE, SIZE);
}
}
cout << sum << endl;
return 0;
}

Segmentation Fault In Probability Calculator

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.

Detrminant of a Matrix n x n

Who can tell me my mistake?
The determinant isnĀ“t correct!
I did a test in a piece of paper and the answer is correct!
I believe that maybe my mistake is in the while, in the line "Matriz[i+1][j] = (Matriz[i+1][j] - (Matriz[fila][j]*(Matriz[i+1][0]/Matriz[fila][fila]))); " but my test is correct.
#include <iostream>
#include <stdio.h>
using namespace std;
class Matriznxm{
private:
int n,m;
float **Matriz;
public:
Matriznxm(int f, int c){
n = f;
m = c;
Matriz = new float *[n];
for (int i=0; i<n; i++){
Matriz[i]=new float [m];
}
for(int i=0; i<n; i++){
for(int j=0; j<m; j++ ){
Matriz[i][j]=0.0;
}
}
}
void llenarMatriz(){
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
cout << "\nMatriz ["<<i+1<<"]["<<j+1<<"]: ";
cin >> Matriz[i][j];
}
}
}
void mostrarMatriz(){
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
cout << Matriz[i][j]<< " ";
}
cout << "\n";
}
}
int determinante(){
float det = 1.0;
int fila = 0;
while(fila < n-1){
for(int i=fila; i<n-1; i++){
for(int j=fila; j<m; j++){
Matriz[i+1][j] = (Matriz[i+1][j] - (Matriz[fila][j]*(Matriz[i+1][0]/Matriz[fila][fila])));
}
}
fila++;
}
for (int i=0; i<n; i++){
det= det * Matriz[i][i];
}
return det;
}
};
int main(){
int n,m;
cout<<"\nNumero de Filas y Columnas: ";
cin >> n;
cout << "\n\n\n";
m=n;
Matriznxm m1(n,m);
m1.llenarMatriz();
m1.mostrarMatriz();
cout << "\nEl determinante es: "<< m1.determinante() <<"\n\n";
m1.mostrarMatriz();
return 1;
}
#include <iostream>
using namespace std;
int main()
{
int siz;
cout<< "enter the size of you matrix AxA\nA = ";
cin >>siz;
int mat[siz][siz],rez=0,rezA=1,rezB=1;
for(int i=0;i<siz;i++)
for(int j=0;j<siz;j++)
cin >> mat[i][j];
for(int t=0;t<siz;t++){
for(int i=0;i<siz;i++)
{
rezA = rezA *mat[i][i+t>siz-1?(i+t-siz):i+t];
rezB = rezB *mat[i][siz-t-1-i<0?(2*siz-t-1-i):(siz-t-1-i)];
}
rez = rez + (rezA - rezB);
rezA =rezB = 1;
}
cout <<endl<<"The Determinat is : "<<rez;
return 0;
}

Passing 3D dynamic array by reference

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