Pointer to a Matrix is throwing exception in c++ [duplicate] - c++

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;

Related

return 2D array in C++

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;

Two-dimensional dynamic allocated arrays created inside a class in C++ [duplicate]

This question already has answers here:
What is The Rule of Three?
(8 answers)
Closed 7 years ago.
I'm relatively new at c++ and other object oriented languages as a whole (have done one semester of C classes and now I'm having c++ classes). I'm having problems concerning the making of a dynamically allocated two-dimensional array through a class with a classmate.
The exercise itself would be:
Prepare a class named "matrix" capable of storing two-dimensional
arrays dynamically allocated (for float variables). Remember that
information such as height and width have to be properly stored
somewhere, element pointers too.
The class needs to contain constructors that allow the creation of
objects using one of the following strategies: The creation of an
array consisting of MxN elements, example:
Array A (4, 5);
The creation of an empty array:
Array B;
The creation of an array that is a copy of another previous one:
Array C (A);
After some time trying to figure out why it wasn't working properly, our code is currently this:
obs: "Matriz" is how we call a two-dimensional array in our language.
Matriz.h
#pragma once
class Matriz{
public:
int l, c;
float** matriz;
void setL(int _l);
void setC(int _c);
int getL();
int getC();
Matriz();
Matriz(int _l, int _c);
Matriz(Matriz& m);
float **getMatriz();
float getElement(int pL, int pC);
void setElement(int pL, int pC, float value);
};
Matriz.cpp
#include "Matriz.h"
Matriz::Matriz(){
l = c = 0;
matriz = new float*[l];
for (int i = 0; i<l; i++) {
matriz[l] = new float[c];
}
}
Matriz::Matriz(Matriz& m){
l = m.getL();
c = m.getC();
matriz = new float*[l];
for (int i = 0; i<l; i++) {
matriz[l] = new float[c];
}
for (int i = 0; i<l; i++) {
for (int j = 0; j<l; j++) {
matriz[i][j] = m.matriz[i][j];
}
}
}
Matriz::Matriz(int _l, int _c){
l = _l;
c = _c;
matriz = new float*[l];
for (int i = 0; i<l; i++) {
matriz[l] = new float[c];
}
}
float **Matriz::getMatriz(){
return matriz;
}
int Matriz::getC(){
return c;
}
int Matriz::getL(){
return l;
}
void Matriz::setC(int _c){
c = _c;
}
void Matriz::setL(int _l){
l = _l;
}
float Matriz::getElement(int pL, int pC){
return matriz[pL][pC];
}
void Matriz::setElement(int pL, int pC, float value){
matriz[pL][pC] = value;
}
main.cpp
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
int l = 2, c = 2;
float **m;
m = new float*[l];
for (int i=0; i<2; i++) {
m[i] = new float[c];
}
Matriz a(2, 2);
a.setC(2);
a.setL(2);
cout << " c = " << a.getC() << " l= " << a.getL() << "\n";
for (int i = 0; i<l; i++) {
for (int j = 0; j<c; j++) {
a.setElement(i, j, 0);
cout << " Elemento " << 1 << " " << 1 << " = " << a.getElement(l, c) << "\n";
}
}
a.setElement(0, 0, 1); // <- this is just for testing
system("pause");
}
iostream and the class header are both included at stdafx.h
Compiling it at MSVS 2013 breaks at
void Matriz::setElement(int pL, int pC, float value){
matriz[pL][pC] = value;
}
And we're not really sure why, the debugger is giving me
"Unhandled exception at 0x01092E27 in ConsoleApplication15.exe: 0xC0000005: Access violation writing location 0xCDCDCDD1."
We suspect however that something with the array is wrong, and when the program tries to write something into an element of it, it simply doesn't exist/can't be reached, making it impossible to change the value of that specific element.
We're thankful for any help or advice, fell free to suggest improvements or coding advices, learning new things is always good =).
I think your error is actually here: a.getElement(l, c). l and c are the bounds for the array, e.g. 2, when your largest index should only ever be 1.
The other serious flaw (pointed out by twsaef) is your constructor:
for (int i = 0; i<l; i++) {
matriz[l] = new float[c];
}
Should be
for (int i = 0; i<l; i++) {
matriz[i] = new float[c];
}
While I'm at it, this is redundant:
Matriz a(2, 2);
a.setC(2);
a.setL(2);
Because the constructor for Matriz will set l and c for you.
Also, what are you planning on doing with this:
float **m;
m = new float*[l];
for (int i=0; i<2; i++) {
m[i] = new float[c];
}
Currently it's not used for anything.
Then, as PaulMcKenzie pointed out, what will happen to your dynamically allocated memory when a Matriz instance goes out of scope?
As Matt McNabb pointed out, what if you need to resize a Matriz instance when setC() or setL() are called? At the moment, they only set the member variable and do nothing with the memory.

Strange behavior of pointer to array in C++

I wrote this program which uses recursion to calculate the determinant of a matrix.
I have a problem with the function build_new_matrix (which is not recursive) because it changes the variable old_mat, although I can't see why!
#include <iostream>
#include <cstring>
using namespace std;
int * new_mat = new int[];
int calculate_det_small (int matrix [4]){ //calculate determinant of a 2x2 matrix
int res = ((matrix[0])*(matrix[3]))-((matrix[1])*(matrix[2]));
return res;
};
int * build_new_matrix (int* old_mat, int rows, int minor){ //return the minor of the matrix
int l=0;
for (int i=rows; i<(rows*rows); i++){
cout<<old_mat[i]<<" ";
if ((i-minor) % rows !=0){
new_mat [l] = old_mat[i] ; ///////////////////error!!!!!!!!
l++;
}
};
return new_mat;
};
int calculate_det (int rows, int matrix[]) { //calculate determinant of a bigger matrix
int c,o;
if (rows==2){
return calculate_det_small (matrix);
}
else {
int result=0;
for (int i=0; i<rows;i++){
int* cur_matrix = build_new_matrix(matrix,rows,i);
if (i%2==0){
c = matrix[i];
result+= ((matrix[i])*(calculate_det((rows-1),cur_matrix)));
}
else{
o =matrix[i];
result-= ((matrix[i])*(calculate_det((rows-1),cur_matrix)));
}
};
return result;
}
};
void main(){
int mat[16] = {1,2,3,4,5,6,7,8,9, 10, 11, 12, 10, 14 ,15, 16};
int determinanta = calculate_det(4,mat);
}
Because, after the first recursion, old_mat points to the same array as the global new_mat; so writing to new_mat overwrites the old matrix. If you're going to do it this way, you'll need to allocate memory for a new matrix at each recursion depth.
Also, new int[] makes no sense, and shouldn't compile. You need to specify the array size.
int * new_mat = new int[];
This line makes no sense. You allocate array with zero elements. Does that even compile?

Segmentation Fault in Linux C++ but code is working in windows

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

Recognizing an integer as a float in 2 dimensional array subscript

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