AoA,
Here is the code of multiplication of two matrices, which runs fine under 3x3 matrices but gives error on exceding row or column of 3x3, like on 3x4 and 4x3 it gives the error "segmentation fault"
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
struct matrix
{
int** mat;
int row;
int col;
matrix(int m,int n)
{
row = m;
col = n;
mat = new int*[row];
for( int i=0;i<row;i++ )
{
mat[i] = new int[col];
for( int k=0;k<col;k++ )
{
mat[i][k] = 0;
}
}
}
};
matrix* MultiplyMat(matrix* matA,matrix* matB)
{
matrix* tMat = new matrix(matA->row,matB->col);
if(matA->row == matB->col)
{
for( int i=0; i<matA->row; i++ )
{
for( int j=0;j<matB->col;j++ )
{
for( int m=0;m<matB->col;m++ )
{
tMat->mat[j][i] += matA->mat[j][m] * matB->mat[m][i];
}
}
}
}
return tMat;
}
void PrintMatrix(matrix* tMat)
{
cout<<"Print: Matrix\n\n";
for( int i=0;tMat->row;i++ )
{
for( int j=0;j<tMat->col;j++ )
{
cout<<" "<<tMat->mat[i][j];
}
cout<<"\n";
}
}
int main()
{
matrix matB(3,4);
matrix matA(4,3);
matA.mat[0][0] = 2;
matA.mat[0][1] = 1;
matA.mat[0][2] = 4;
matA.mat[1][0] = 6;
matA.mat[1][1] = 5;
matA.mat[1][2] = 9;
matA.mat[2][0] = 8;
matA.mat[2][1] = 7;
matA.mat[2][2] = 11;
matA.mat[3][0] = 5;
matA.mat[3][1] = 5;
matA.mat[3][2] = 9;
matB.mat[0][0] = 2;
matB.mat[0][1] = 1;
matB.mat[0][2] = 4;
matB.mat[0][3] = 3;
matB.mat[1][0] = 6;
matB.mat[1][1] = 5;
matB.mat[1][2] = 9;
matB.mat[1][3] = 12;
matB.mat[2][0] = 8;
matB.mat[2][1] = 7;
matB.mat[2][2] = 11;
matB.mat[2][3] = 13;
matrix* matC = MultiplyMat(&matA,&matB);
PrintMatrix(matC);
return 0;
}
I am just trying to multiplay two matrices, the g++ compiler gives error "segmentation fault" I have tried debuging method(found on this site) but failed to remove the error!
Any help?
This line is wrong:
matrix* tMat = (matrix*)malloc(sizeof(matrix));
I'm not entirely sure what you are expecting this to do, but it probably doesn't do that... In fact, it doesn't do much at all, other than create a block of memory large enough for a the struct matrix. It is filled with some random garbage (which may or may not be zeros).
You then go on and use it:
tMat->mat[j][i] += matA->mat[j][m] * matB->mat[m][i];
which most likely means you are either accessing NULL or some random garbage address that isn't valid. You then return the pointer to it, which is not freed here:
matrix* matC = MultiplyMat(&matA,&matB);
PrintMatrix(matC);
return 0;
You probably want something like:
matrix* tMat = new matrix(matB->col, matA->row);
But you would be much better off creating a matrix operator*(const matrix& a, const matrix& b), so you don't return a pointer at all. The overhead will be pretty small.
Your matrix actually has a constructor but it isn't called when allocation memory using malloc(). You clearly want to use
matrix* tMat = new matrix(m, n);
with suitable argument m and n. Well, actually, you rather want to use
std::unique_ptr<matrix> tMat(new matrix(m, n));
... but this is just related to the next problem you'll get once you get past your segmentation fault: you also need to clean up resources. It is also not quite what your really want, though, because you really want something like this:
matrix MultiplyMat(matrix const& a, matrix const& b) {
// ...
matrix result(m, n);
// ...
return result;
}
Related
I am kind of new to C++ and I was doing a physics simulation in python which was taking forever to finish so I decided to switch to C++, and I don t understand how to make a function which will return a 2D array (or 3D array)
#include <iostream>
#include <cmath>
// #include <complex> //
using namespace std;
double** psiinit(int L, int n, double alpha){
double yj[400][400] = {};
for (int j = 0; j < n; j++)
{
double xi[400] = {};
for (int i = 0; i < n; i++)
{
xi[i] = exp(-(pow((i-(L/4)), 2) + (pow((j-(L/4)), 2)))/alpha) / (sqrt(2)*3.14159*alpha);
};
yj[j] = xi;
};
return yj;
}
int main(){
int L = 10;
int n = 400;
int nt = 200*n;
double alpha = 1;
double m = 1;
double hbar = 1;
double x[n] = {};
double y[n] = {};
double t[nt] = {};
double psi[nt][n][n] = {};
psi[0] = psiinit(L, n, alpha);
cout << psi <<endl;
return 0;
}
I have look for answers but it doesn't seems to be for my kind of problems
Thanks
If you're new to c++ you should read about the concepts of heap and stack, and about stack frames. There are a ton of good resources for that.
In short, when you declare a C-style array (such as yj), it is created in the stack frame of the function, and therefore there are no guarantees about it once you exit the frame, and your program invokes undefined behavior when it references that returned array.
There are 3 options:
Pass the array to the function as an output parameter (very C-style and not recommended).
Wrap the array in a class (like std::array already does for you), in which case it remains on the stack and is copied to the calling frame when returned, but then its size has to be known at compile time.
Allocate the array on the heap and return it, which seems to me to best suit your case. std::vector does that for you:
std::vector<std::vector<double>> psiinit(int L, int n, double alpha){
std::vector<std::vector<double>> yj;
for (int j = 0; j < n; j++)
{
std::vector<double> xi;
for (int i = 0; i < n; i++)
{
const int value = exp(-(pow((i-(L/4)), 2) + (pow((j-(L/4)), 2)))/alpha) / (sqrt(2)*3.14159*alpha);
xi.push_back(value);
}
yj.push_back(xi);
}
return yj;
}
If you're concerned with performance and all of your inner vectors are of a fixed size N, it might be better to use std::vector<std::array<double, N>>.
Either make a wrapper as said above, or use a vector of vectors.
#include <vector>
#include <iostream>
auto get_2d_array()
{
// use std::vector since it will allocate (the large amount of) data on the heap
// construct a vector of 400 vectors with 400 doubles each
std::vector<std::vector<double>> arr(400, std::vector<double>(400));
arr[100][100] = 3.14;
return arr;
}
int main()
{
auto arr = get_2d_array();
std::cout << arr[100][100];
}
Your understanding of arrays, pointers and return values is incomplete. I cannot write you a whole tutorial on the topic but I recommend you read up on this.
In the mean time, I recommend you use std::vector instead of C-style arrays and treat your multidimensional arrays as 1D vectors with proper indexing, e.g. cell = vector[row * cols + col]
Something like this:
#include <cmath>
// using std::exp, M_PI, M_SQRT2
#include <vector>
std::vector<double> psiinit(int L, int n, double alpha) {
std::vector<double> yj(n * n);
double div = M_SQRT2 * M_PI * alpha;
for (int j = 0; j < n; j++)
{
double jval = j - L/4;
jval = jval * jval;
for (int i = 0; i < n; i++)
{
double ival = i - L/4;
ival = ival * ival;
yj[j * n + i] = std::exp(-(ival + jval) / alpha) / div;
}
}
return yj;
}
Addendum: There are also specialized libraries to support matrices better and faster. For example Eigen
https://eigen.tuxfamily.org/dox/GettingStarted.html
heap allocating and returning that pointer will also work...
instead of
double yj[400][400] = {};
do,
double** yj;
yj = new double*[400];
yj[i] = new double[400];
then just,
return yj;
I'm working on graph implementations in C++ and came across an implementation for an adjacency matrix that mostly made sense to me. The implementation uses an "init" function to initialize the matrix:
void init(int n) {
numVertex = 0;
numEdge = 0;
mark = new int[n]; //initialize mark array
for (int i = 0; i < numVertex; i++) {
mark[i] = 0;
}
matrix = (int**) new int*[numVertex]; //make matrix
for (int i = 0; i < numVertex; i++) {
matrix[i] = new int[numVertex];
}
for (int i = 0; i < numVertex; i++) { //mark all matrix cells as false
for (int j = 0; j < numVertex; j++) {
matrix[i][j] = 0;
}
}
}
The line I'm confused about is:
matrix = (int**) new int*[numVertex]; //make matrix
What does the (int**) aspect do? Why would I choose to use this instead of matrix = new int**[numVertex];?
Thanks so much!
(int**)value is a C-style cast operation.
Notes:
Don't use those in C++, it tends to cause or hide problems, like mismatches between right and left side of an assignment.
The code is relatively low quality, proper C++ would rather use std::vector.
The code is also not complete, so little can be said with certainty about how it functions.
Note that matrix = new int**[numVertex]; as mentioned by you would create (for this example) a 3D array, because you'd have numVertex entries of int**.
The (int**) cast does not accomplish much, if anything at all, because if matrix is of type int**, there is no need for the cast (you get back an int** already from the new).
If column dimension is fixed, you can use vector of array there.
godbolt
wandbox
#include <vector>
#include <array>
#include <iostream>
#include <iomanip>
template<typename T, int col>
using row_templ = std::array<T,col>;
template<typename T, int col, template <typename,int> typename U = row_templ>
using mat_templ = std::vector<U<T,col>>;
int main()
{
constexpr int numVertex = 30;
constexpr int numEdge = 30;
constexpr int numCol = numVertex;
int numRow = numEdge;
using row_t = row_templ<int, numCol>; // alias to the explicit class template specialization
using mat_t = mat_templ<int, numCol>;
auto make_mat = [&](){ return mat_t(numRow); }; // define a maker if lazy
mat_t my_mat(numRow);
mat_t my_mat2 = make_mat(); // or just use our maker
// Due to that default allocator uses value initialization, a.k.a T().
// At this point, all positions are value init to int(), which is zero,
// from value init of array<int, col>() by the default allocator.
// numVertex x numEdge is one solid contaguous chunk and now ready to roll.
// range for
for (row_t r : my_mat) {
for (int n : r) {
std::cout << std::setw(4) << n;
}
std::cout << '\n';
}
// classic for
for (int i = 0; i < numRow; ++i) {
for (int j = 0; j < numCol; ++j) {
std::cout << std::setw(4) << (my_mat2[i][j] = i*numRow + numCol);
}
std::cout << '\n';
}
}
There are other posts about common causes of segmentation faults, but I don't think the built-in array object I've created here (result) doesn't go out of bounds when I assign values to it.
I think this could be helpful to people in the future who have arrays not out of bounds, and I also haven't seen a lot of stuff about making 2D built-in array objects - examples I've seen are almost entirely vectors or std:array objects.
Here is runnable, relevant code:
matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include <initializer_list>
using std::initializer_list;
typedef unsigned int uint;
class Matrix {
public:
Matrix(uint rows, uint cols);
~Matrix();
Matrix add(double s) const;
const uint numRows() const;
const uint numCols() const;
double & at(uint row, uint col);
const double & at(uint row, uint col) const;
private:
uint rows, cols;
double ** matrix;
void makeArray() {
matrix = new double * [rows];
for(uint i = 0; i < rows; ++i) {
matrix[i] = new double [cols];
}
}
};
#endif
matrix.cpp
#include "matrix.h"
Matrix::Matrix(uint rows, uint cols) {
//Make matrix of desired size
this->rows = rows;
this->cols = cols;
makeArray();
//Initialize all elements to 0
for(uint i = 0; i < rows; ++i) {
for(uint j = 0; j < cols; ++j) {
this->matrix[i][j] = 0.0;
}
}
}
Matrix::~Matrix() {
for(uint i = 0; i < numRows(); ++i) {
delete[] matrix[i];
}
delete[] matrix;
}
const uint Matrix::numRows() const {
return this->rows;
}
const uint Matrix::numCols() const {
return this->cols;
}
double & Matrix::at(uint row, uint col) {
return matrix[row][col];
}
const double & Matrix::at(uint row, uint col) const {
return matrix[row][col];
}
Matrix Matrix::add(double s) const {
uint r = this->numRows();
uint c = this->numCols();
Matrix * result;
result = new Matrix(r, c);
for(uint i = 0; i < r; ++i) {
for(uint j = 0; j < c; ++j) {
result->at(i,j) = (this->at(i,j)) + s;
}
}
return * result;
}
main.cpp
#include <iostream>
#include <cstdlib>
#include "matrix.h"
using namespace std;
typedef unsigned int uint;
int main() {
Matrix * matrix;
matrix = new Matrix(3, 2); //Works fine
double scaler = 5;
matrix->at(2,1) = 5.0; //Works fine
Matrix r = matrix->add(scaler); //DOESN'T WORK
return EXIT_SUCCESS;
}
Any ideas why the add function is causing a segmentation fault error? The for-loop I used to fill the result Matrix object doesn't go out of bounds, and I'm not familiar enough with C++ to know what else could be causing it.
Thanks in advance.
The problem is lack of a manually defined copy constructor or assignment operator, given that the class manages a resource (memory).
If an instance of the class is assigned, or used to create a copy, the result will be two distinct objects that reference the same memory. When those two objects which refer to the same memory are destroyed, the memory is released twice. The result of that is undefined behaviour.
Look up the "rule of three" for a solution. In C++11, that often becomes a "rule of five" or a "rule of zero" (which involves using techniques to avoid the problem in the first place).
There is also a pretty significant problem in the add() function, since it dynamically creates a Matrix, then returns a copy of it. That causes a memory leak, even if the problem with copying the object is resolved. That function actually looks like something which would be written in a garbage collected language - the problem being that C++ is not garbage collected.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I work with dynamic multi-dimensional arrays in C?
Static Matrix Casting to a pointer
my this code is throwing exception at line
resMat[i][j] = matp[i][j];
// code begins here
#include <iostream>
#define MOD 1000000007
#define LL long long
using namespace std;
int mat[6][64][64],mat2[2][2], mat4[4][4], mat8[8][8], mat16[16][16], mat32[32][32], mat64[64][64];
int **point[6];
int resMat[64][64];
void fooMatrix(int **matp, int size)
{
int i,j;
// find canFollow of all matrixes
for(i=0;i<size;++i)
{
for(j=0;j<size;++j)
{
// throwing exception here
resMat[i][j] = matp[i][j];
}
}
}
int main()
{
point[0] = (int **)mat2;
point[1] = (int **)mat4;
point[2] = (int **)mat8;
point[3] = (int **)mat16;
point[4] = (int **)mat32;
point[5] = (int **)mat64;
LL a,b,res;
scanf("%lld %lld",&a,&b);
fooMatrix(point[a-1],1<<a);
return 0;
}
i want to process on different sized matrices of int in my function fooMatrix like say store it in resMat. Help me resolve this issue.
I am using DevC++ (g++ compiler) in windows.
Reading from the comments and links above i learnt this :
matrix represntation [][] and pointers representation ** is different. Compiler was giving me warning.
2d matrix is not array of pointers. so look at the code below
#include <stdio.h>
#define MOD 1000000007
#define LL long long
int mat[6][64][64],mat2[2][2], mat4[4][4], mat8[8][8], mat16[16][16], mat32[32][32], mat64[64][64];
// see this is array of single pointer
int *point[6];
int resMat[64][64];
void fooMatrix(int *matp, int size)
{
int i,j;
// find canFollow of all matrixes
for(i=0;i<size;++i)
{
for(j=0;j<size;++j)
{
// this is how we would access the matrix.
resMat[i][j] = matp[i*size+j];
}
}
}
int main()
{
point[0] = &mat2[0][0];
point[1] = &mat4[0][0];
point[2] = &mat8[0][0];
point[3] = &mat16[0][0];
point[4] = &mat32[0][0];
point[5] = &mat64[0][0];
LL a,b,res;
scanf("%lld %lld",&a,&b);
fooMatrix(point[a-1],1<<a);
return 0;
}
Instead of using matrices, you will have to use dynamically allocated arrays of pointers to arrays.
You can replace the declarations at the top of the file with the following:
int** newMat(int a, int b){
int** result = new int*[a];
for(int i=0; i<a; ++i)
result[i] = new int[b];
return result;
}
int** mat2 = newMat(2,2);
int** mat4 = newMat(4,4);
int** mat8 = newMat(8,8);
int** mat16 = newMat(16,16);
int** mat32 = newMat(32,32);
int** mat64 = newMat(64,64);
int*** point = new int**[6];
int** resMat= newMat(64,64);
And then change the assignments at the top of main with:
point[0] = mat2;
point[1] = mat4;
point[2] = mat8;
point[3] = mat16;
point[4] = mat32;
point[5] = mat64;
Here's the code that I'm currently using
template <class T>
float Knapsack<T>::knapTable()
{
const int MAXSIZE = 40000;
int temps = nObjects - 1;
float** memoize = new float*[MAXSIZE];
for(int y = 0; y < weight[nObjects]; y++)
memoize[nObjects][y] = 0;
for(int y = weight[nObjects]; y < knapCap; y++)
memoize[nObjects][y] = price[y];
for(int i = temps; i >= 1; i--)
{
for(int y = weight[i]; y < knapCap; y++)
memoize[i][y]= max(memoize[i+1][y], (memoize[i+1][y-weight[i]]+price[i]));
}
return memoize[1][nObjects];
}
For some reason I keep getting the error: knapsack.hpp:68:64: error: invalid types ‘float*[float]’ for array subscript.
That's this line: float** memoize = new float*[MAXSIZE];
For some reason the compiler seems to be recognizing MAXSIZE as a float, it's a const int.
Is there a way I can fix this?
Edited for more code
header file
#ifndef KNAPSACK_H
#define KNAPSACK_H
#include <stdexcept>
#include <assert.h>
#include <iostream>
#include <limits.h>
using namespace std;
template <class T>
class Knapsack
{
private:
float knapPrice;
int knapCap, nObjects;
float weight[40000];
float price[40000];
public:
Knapsack(): knapPrice(0), knapCap(0), nObjects(0) {}
~Knapsack() {knapPrice = 0; knapCap = 0;}
float knapFull (int position, int currentCap);
float knapTable ();
float greedyKnap (int currentCap);
float max(float noAdd,float addOb);
void printPrice();
//valueized and valued are modified versions of mergeSort and merge
//designed to sort two arrays by a fraction of the two.
void valueize(int ini, int last);
void valued(int ini, int middle, int last);
void fillWandP();
void setNObjects(int n);
void setKnapCap(int boom);
};
#include "knapsack.hpp"
#endif
Main function //Though I don't think this would affect it
#include "sortClass.h"
#include "knapsack.h"
#include
#include
#include
#include
using namespace std;
//mergeSort main;
int main()
{
Knapsack<float> a;
float sacked = 0;
int nO = 18;
int cap = 700;
a.setNObjects(nO);
a.setKnapCap(cap);
a.fillWandP();
for(int b = 0; b <3800000; b++)//for getting good times
sacked = b;
int startAll = clock()*1000000;
sacked = a.knapFull(1, cap);
int knapped = clock()*1000000;
int boom = a.knapTable();
int tabled = clock()*1000000;
a.valueize(1, cap);
int andDone = a.greedyKnap(cap);
int greedified = clock()*1000000;
cout<<startAll<<endl;
greedified = greedified - tabled;
tabled = tabled - knapped;
knapped = knapped - startAll;
cout<<"Recursion profit:"<<sacked<<" Time: "<<knapped<<endl;
cout<<"Memoization profit:"<<boom<<" Time: "<<tabled<<endl;
cout<<"Greedy profit: "<<andDone<<" Time: "<<greedified<<endl;
return 0;
}
weight is declared as float weight[40000] in class Knapsack.
You then use an element of weight as an index into memoize in the knaptable() function:
memoize[i][y]= max(memoize[i+1][y], (memoize[i+1][y-weight[i]]+price[i]));
// ^^^^^^^^^
And for the record, that's the line that the error is produced for by g++ 4.6.1; it doesn't point to the line where memoize is declared.
Not necessarily related, but you're not using your arrays/pointers correctly. You create your first level of pointers when you call float** memoize = new float*[MAXSIZE] but you then just have an array of pointers, not a double array. You need to initialize each of memoize[i] as an array as well.
That being said, it doesn't look like you should be allocating memory for your memoize array anyway. Just declare it as
float memoize[SIZE][SIZE];
That way, you won't have to worry about memory cleanup or anything, and it makes a lot more sense.
for(int i = temps; i >= 1; i--)
{
for(int y = weight[i]; y < knapCap; y++)
memoize[i][y]= max(memoize[i+1][y], (memoize[i+1][y-weight[i]]+price[i]));
}
y-weight[i] is a float. This is your problem.
Once you fix this you will discover that you still have an issue, you're allocating an array of pointers but you also need to allocate the second dimension for each of those pointers before you can use that array.
Something along the lines of:
float** memoize = new float*[MAXSIZE];
for(size_t i = 0; i < MAXSIZE; ++i)
{
memoize[i] = new float[MAXSIZE];
}
i think maybe you just need to allocate memory for the second pointer ,something like
float** memoize = new float*[MAXSIZE];
memoize=(float**)malloc(sizeof(float*)*MAXSIZE);
for(int i=0;i<MAXSIZE;i++)
{
memoize[i]=(float*)malloc(sizeof(float)*MAXSIZE);
}