Can't understand reason of the SIGTRAP in c++ code - c++

I am writing some function for work with matrix.
I received correct output:
__11111111
__11111111
__333333333
__444444444444
But then program didn't stop and return invalid code
Process finished with exit code -1073741819 (0xC0000005)
How can i fix the error?
I tried debugger (gdb) and found out this:
Signal = SIGTRAP
And debugger presented me file new_allocator.h (attempt to deallocate nullptr)
// __p is not permitted to be a null pointer.
void
deallocate(pointer __p, size_type)
{ ::operator delete(__p); }
My code
#include <bits/stdc++.h>
using namespace std;
#define EPS 0.000001
int dualMatrix(vector<vector<double>> a) {
int n = a.size();
int m = a[0].size();
for (int col=0, row=0; col<m && row<n; ++col) {
int sel = row;
for (int i=row; i<n; ++i)
if (abs (a[i][col]) > abs(a[sel][col]))
sel = i;
if (abs(a[sel][col]) < EPS)
continue;
for (int i=col; i<=m; ++i)
swap(a[sel][i], a[row][i]);
cout << "__11111111\n";
for (int i=0; i<n; ++i)
if (i != row) {
if (a[row][col] == 0) {
cout << "DIVIDER IS ZERO" << endl;
return -1;
}
double c = a[i][col] / a[row][col];
for (int j=col; j<=m; ++j)
a[i][j] -= a[row][j] * c;
}
++row;
}
int rank = 0;
for (int i = 0; i < n; ++i) {
double temp = a[i][i];
if (temp == 0) {
cout << "Diagonal element is 0 at the row=" << i << endl;
rank = i;
break;
}
for (int j = 0; j < m; ++j) {
a[i][j] /= temp;
}
}
cout << "__333333333\n";
//printMatrix(a);
cout << "__444444444444\n";
return 0;
}
int main() {
vector<vector<double>> tmp {{1, 2, 3}, {3, 4, 5}};
dualMatrix(tmp);
cout << "__END" << endl;
return 0;
}

int m = a[0].size();
The size of the vector is m
for (int i=col; i<=m; ++i)
swap(a[sel][i], a[row][i]);
Here, i is outside the bounds of the vectorsa[sel] and a[row]. Accessing the vector outside of its bounds with the subscript operator has undefined behaviour.
Same here:
for (int j=col; j<=m; ++j)
a[i][j] -= a[row][j] * c;
How can i fix the error?
Don't access the vector outside of its bounds. If the size of the vector is 3, then the valid indices are 0, 1 and 2. If the size if m, then valid indices are 0, ..., m - 1

Related

Segmentation fault in matrix multiplication C++

I'm trying to make a function that receives as parameter two matrixes and returns the multiplication of both. But when I try to test it, it returns a segmentation fault, can anyone tell me why? And help me to fix it?
This is my function code:
#include <iostream>
#include <math.h>
#include <fstream>
#include <vector>
using namespace std;
vector<vector<double> > MMultiplication(vector<vector<double> > a, vector<vector<double> > b) {
int a_columns = a[0].size();
int a_rows = a.size();
int b_columns = b[0].size();
int b_rows = b.size();
< vector<vector<double> > result;
result.resize(a_columns);
for (int i = 0; i < m; ++i)
{
//Grow Columns by b_rows
result[i].resize(b_rows);
}
for (int p = 0; p < a_rows; p++) {
for (int q = 0; q < b_columns; q++) {
result[p][q] = 0;
}
}
if (a_columns != b_rows) {
cout << "Error: The number of columns of the first matrix needs to be equal to the number of rows of the second matrix" << endl;
return result;
}
for (int i = 0; i < a_rows; i++) { //i iterate a rows
for (int j = 0; j = b_columns; j++) //j iterates b columns
{
for (int k = 0; k < a_columns; k++) { //k goes back to a and iterates its columns
result[i][j] += a[i][k] * b[k][j]; //sums all multiplications into result[i][j]
}
}
}
return result;
}
And this is the main i'm using to test my function:
int main ()
{
vector < vector < double >>a;
int m = 4, n = 2;
//Grow rows by m
a.resize (m);
for (int i = 0; i < m; ++i)
{
//Grow Columns by n
a[i].resize (n);
}
a[0] =
{
1, 0};
a[1] =
{
1, 1};
a[2] =
{
1, 2};
a[3] =
{
1, 3};
cout << a.size () << endl;
cout << a[0].size () << endl;
vector < vector < double >>b;
int o = 2, p = 4;
b.resize (o);
for (int i = 0; i < o; i++)
{
b[i].resize (p);
}
b[0] =
{
1, 2, 3, 4};
b[1] =
{
1, 3, 5, 7};
vector < vector < double >>result = MMultiplication (a, b);
cout << result.size () << endl;
cout << result[0].size () << endl;
/* for(int k = 0; k < result.size(); k++) {
for(int q = 0; q < result[0].size(); q++)
cout << result[k][q] << endl;
} */
}
Also, it's important to point out that the function, so far, is returning a matrix of zeros if it's impossible to multiply a and b.
Thank you.

Heap corruption detected error in C++

Here is my code:
#include<iostream>
#include<cstdlib>
using namespace std;
int main() {
int** arr=NULL;
int num=0;
cin >> num;
int* big=NULL;
arr = new int*[num];
for (int i = 0; i < num; i++) {
arr[i] = new int[5];
}
big = new int[num];
for (int i = 0; i < num; i++) {
for (int j = 0; j < 5; j++) {
while (1) {
cin >> arr[i][j];
if (arr[i][j] >= 0 && arr[i][j] < 100)
break;
}
}
}
for (int i = 0; i < 5; i++) {
big[i] = 0;
}
for (int i = 0; i < num; i++) {
for (int j = 0; j < 5; j++) {
if (big[i] < arr[i][j]) {
big[i] = arr[i][j];
}
}
}
for (int i = 0; i < num; i++) {
cout << "Case #" << i + 1 << ": " << big[i] << endl;
}
delete[]big;
for (int i = num-1; i>=0; i--) {
delete[]arr[i];
}
delete[]arr;
return 0;
}
When I run this code, it says that there are heap corruption error (heap corruption detected). I think it means that there are some errors at 'new' or 'delete' parts in my codes, but I cannot find them. I hope someone to answer. Thanks.
Error is here:
big = new int[num];
...
for (int i = 0; i < 5; i++) {
big[i] = 0;
}
So when you have num less than 5 you are writing outside the array.
Anyway you are using C++ so use vector for such tasks.
#include<iostream>
#include<cstdlib>
#include<vector>
using namespace std;
int main() {
vector<vector<int>> arr;
int num=0;
cin >> num;
arr.resize(num, vector<int>(5));
for (auto &row : arr) {
for (auto &cell : row) {
while (1) {
cin >> cell ;
if (cell >= 0 && cell < 100)
break;
}
}
}
vector<int> big(arr.size());
for (int i = 0; i < arr.size(); i++) {
for (auto &cell : arr[i]) {
if (big[i] < cell) {
big[i] = cell;
}
}
}
for (int i = 0; i < num; i++) {
cout << "Case #" << i + 1 << ": " << big[i] << endl;
}
return 0;
}
In many places in your code, you're indexing your big array using indexes from 0 to 5, while the array is allocated using user input, if user input was 4 for example, your code is undefined behavior.
If you're using c++, you shouldn't be manually allocating the arrays, use std::vector instead, it will take care of managing memory for you, so you don't have to new and delete memory yourself.
With std::vector, your code would look somewhat like this.
std::vector<std::vector<int>> arr;
std::vector<int> big;
cin>>num;
arr.resize(num, std::vector<int>(5));
big.resize(5);
You will also be able to use at method to access elements while bound-checking, and size method to get the number of elements of the array.

Segmentation Fault Error Dealing with Matrices (Arrays)

I'm trying to reference a 2D array object I've constructed, but for whatever reason I'm getting a segmentation fault and I'm having trouble figuring out the cause. So far I've deduced that the error lies in my operator<< function, but I can't figure out what to change.
main.cpp:
int main() {
My_matrix m1(3, 2);
cout << "Before" << endl;
m1(0,0) = 1; //causes segfault
cout << "After" << endl;
m1(0,1) = 2; //causes segfault
m1(1,0) = 3; //causes segfault
m1(1,1) = 4; //causes segfault
m1(2,0) = 5; //causes segfault
m1(2,1) = 6; //causes segfault
cout << "Checkpoint 1" << endl;
My_matrix m2(); //works
cout << "Checkpoint 2" << endl;
cout << m1.number_of_rows() << endl; //works
cout << "Checkpoint 3" << endl;
cout << m1; //Segfault
cout << "Checkpoint 4" << endl;
cout << m1; //Segfault
cout << "Checkpoint 5" << endl;
cout << m2; //Segfault
cout << "Checkpoint 6" << endl;
}
My_matrix.cpp:
#include "My_matrix.h"
#include <stdexcept>
My_matrix::My_matrix()
{
n = 0;
m = 0;
ptr = nullptr;
}
My_matrix::My_matrix(int n1, int m1)
{
n = n1;
m = m1;
ptr = new int*[n];
for(int i = 0; i < n; i++) {
ptr[i] = new int[m];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
ptr[i][j] = 0;
}
}
}
My_matrix::My_matrix(const My_matrix& mat)
{
this->n = mat.n;
this->m = mat.m;
ptr = new int*[n];
for(int i = 0; i < n; i++) {
ptr[i] = new int[m];
}
//----- copy elements over to new matrix -----//
for (int i = 0; i < mat.n; i++) {
for (int j = 0; j < mat.m; j++) {
this->ptr[n][m] = mat.ptr[n][m];
}
}
}
My_matrix::~My_matrix()
{
clear();
}
My_matrix& My_matrix::operator=(const My_matrix& mat)
{
clear();
this->n = mat.n;
this->m = mat.m;
ptr = new int*[n];
for(int i = 0; i < n; i++) {
ptr[i] = new int[m];
}
//----- copy elements over -----//
for (int i = 0; i < mat.n; i++) {
for (int j = 0; j < mat.m; j++) {
this->ptr[n][m] = mat.ptr[n][m];
}
}
}
int My_matrix::number_of_rows() const
{
return n;
}
int My_matrix::number_of_columns() const
{
return m;
}
int* My_matrix::operator()(int i) const
{
return ptr[i];
}
int& My_matrix::operator()(int i, int j) const
{
return ptr[n][m];
}
int& My_matrix::operator()(int i, int j)
{
return ptr[n][m];
}
int& My_matrix::elem(int i, int j) const
{
if (i < 0 || i >= n) throw out_of_range("Out of range");
if (j < 0 || j >= m) throw out_of_range("Out of range");
return ptr[n][m];
}
int& My_matrix::elem(int i, int j)
{
if (i < 0 || i >= n) throw out_of_range("Out of range");
if (j < 0 || j >= m) throw out_of_range("Out of range");
return ptr[n][m];
}
void My_matrix::clear()
{
for (int i = 0; i < n; i++) {
delete[] ptr[i];
}
delete[] ptr;
n = 0;
m = 0;
}
ostream& operator<<(ostream& out, const My_matrix& mat)
{
for (int i = 0; i < mat.number_of_rows(); i++) {
for (int j = 0; j < mat.number_of_columns(); j++) {
out << mat(i, j) << " "; //This line is the culprit ****
}
out << endl;
}
return out;
}
As hinted at by #WhozCraig and #O'Neil in the comments, I had a few typos in my code which referred to indices that were not in bounds of the matrix I had created. Rather than using the iterators/function arguments, I used n and m, which represent the size of the matrix, which is obviously one larger than the largest index. Examples include:
int& My_matrix::elem(int i, int j) const
{
if (i < 0 || i >= n) throw out_of_range("Out of range");
if (j < 0 || j >= m) throw out_of_range("Out of range");
return ptr[n][m]; //<--- should be return ptr[i][j];
}
as well as
My_matrix::My_matrix(const My_matrix& mat)
{
this->n = mat.n;
this->m = mat.m;
ptr = new int*[n];
for(int i = 0; i < n; i++) {
ptr[i] = new int[m];
}
//----- copy elements over to new matrix -----//
for (int i = 0; i < mat.n; i++) {
for (int j = 0; j < mat.m; j++) {
this->ptr[n][m] = mat.ptr[n][m]; //<--- should be this->ptr[i][j] = mat.ptr[i][j];
}
}
}
By correcting these discrepancies my issue was resolved.

HackerRank says ~no response on stdout~. C++

I wrote this solution for the absolute permutation problem on HackerRank. It works fine on dev-C++ but doesn't work on Hackerrank. I've found that the code produces output when I remove the abs_perm(). What's the problem here?
#include <iostream>
using namespace std;
int arr[100000];
int check(int n, int k)
{
if ( (2*k == n) || (k == 0) || (n - 4*k == 0) )
return 1;
else if (k < n/2)
return check(n - 4*k, k);
else
return 0;
}
void swap(int &a, int &b)
{
int c = b;
b = a;
a = c;
}
void ini(int n)
{
for (int i = 0; i < n; i++)
{
arr[i] = i+1;
}
}
void abs_perm(int n, int k)
{
for (int i = 0; i < k; i++)
{
swap(arr[i], arr[k+i]);
}
if (2*k == n)
return;
for (int i = n - 1; i > n - k - 1; i--)
{
swap(arr[i], arr[i-k]);
}
if (n - 4*k == 0)
return;
abs_perm(n - 4*k, k);
}
int main()
{
int T;
cin >> T;
int N[T], K[T];
for (int i = 0; i < T; i++)
{
cin >> N[i] >> K[i];
}
for (int i = 0; i < T; i++)
{
cout << N[i] << " " << K[i] << "\n";
}
for (int i = 0; i < T; i++)
{
if ( !check(N[i], K[i]) )
cout << "-1\n";
else
{
ini(N[i]);
abs_perm(N[i], K[i]);
for (int j = 0; j < N[i]; j++)
{
cout << arr[j] << " ";
}
cout << "\n";
}
}
return 0;
}
Array is a structure to use when you know at compile time the dimension of your structure. What you wrote at the begin in abs_perm() is not correct for standard compilers (in fact you don't know the dimension of your array). You can use a std::vector or a std::list which allocate memory dynamically or (bad solution) you can allocate an array with dimension that certainly contains all elements you will put inside.

Sieve of Eratosthenes implementation

I am trying to implement algorithm for Sieve of Eratosthenes but I don't know why this program crashes for larger programs. Initially I was using vector but now I am implementing this using dynamic memory allocation.
#include<iostream>
#include<cmath>
#include<cstdlib>
using namespace std;
unsigned isqrt(unsigned value) {
return static_cast<unsigned>(sqrt(static_cast<float>(value)));
}
int main()
{
int t;
cin >> t;
long long * N;
long long * M;
long long n, m;
N = new long long[t];
M = new long long[t];
for(int i = 0; i < t ; i++){
cin >> M[i] >> N[i];
}
for(int i = 0; i < t ; i++){
n = N[i];
m = M[i];
bool * A;
A = new bool[n];
if(A == 0)
{
cout << "Memory cannot be allocated";
return 0;
}
for(int i=0;i < n;i++){
A[i]=true;
}
A[0] = false;
A[1] = false;
unsigned sqrt = isqrt(n);
for(int i = 2; i <= sqrt; i++)
{
if(A[i] == true){
for(int j = i*i; j <= n; j = j + i)
{
A[j] = false;
}
}
}
for(int i = m;i < n;i++)
{
if(A[i] == true )
cout << i << "\n";
}
delete[] A;
}
delete[] M;
delete[] N;
return 0;
}
The program crashes for larger values of n and m (~10^16). Kindly help me out.
for(int j = i*i; j <= n; j = j + i)
^^
If j == n then A[j] = false will assign to an element past the end of the array. The test should be j < n.
If you're going to write a sieve of Eratosthenes in C++, how about if you actually use C++, not try to treat it as some demented cross between C and assembly language.
#include <vector>
#include <iostream>
unsigned long primes = 0;
int main() {
int number = 10000000;
std::vector<bool> sieve(number,false);
sieve[0] = sieve[1] = true;
for(int i = 2; i<number; i++) {
if(!sieve[i]) {
++primes;
for (int temp = 2*i; temp<number; temp += i)
sieve[temp] = true;
}
}
std::cout << "found: " << primes << " Primes\n";
return 0;
}
If n is big enough to cause memory allocation error program will crash due to incorrect memory allocation error handling here
A = new bool[n];
if(A == 0)
{
cout << "Memory cannot be allocated";
return 0;
}
new doesn't return 0 on error, but throws std::bad_alloc that doesn't get catched, which in turn will lead to unexpected() then terminate() and finally abort() to be called.
Correct version would be:
try
{
A = new bool[n];
}
catch (std::bad_alloc& ba)
{
std::cerr << "Memory cannot be allocated: " << ba.what() << '\n';
}
Run this in a debugger to determine where the crash is and debug from there. It will most likely be apparent at that point.
You can do this either from an IDE or from command line. In the latter case compile with -g and run in a program such as gdb. Google something like "gdb cheatsheet" to get started.