Reputation: 1015
My code is below. The problem happens when I try and run the addArray() function. I am completely new to C++ so I have no idea what a segmentation fault means.
I also know that there is probably a better way to initialize and return the 2d arrays, but I am slowly figuring that out.
My main problem now is the segmentation fault. I am guessing that it has something to do with how I am accessing the variables?
#include <iostream>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <iomanip>
#include <time.h>
#include <stdlib.h>
using namespace std;
int c, q, w, row, coll, quit, qq, opt;
int** arr1;
int** arr2;
int** ans;
//Method Prototypes
int menu();
inline int** getArray(int opt);
inline void printArray(int** arr, int height, int width);
void addArray();
void subtractArray();
void multiplyArrays();
void determArray();
void transposeArray();
void inverseArray();
//Prints out the menu for choosing which option to go with
int menu() {
cout << "Press 1 for Addition\n";
cout << "Press 2 for Subtraction\n";
cout << "Press 3 for Multiplication\n";
cout << "Press 4 for Determinant\n";
cout << "Press 5 for Transpose\n";
cout << "Press 6 for Inverse\n";
cout << "Press 0 to quit\n\n";
cin >> c;
return c;
}
//Main method
int main(void) {
cout << "C++ 2d Matrix Operations Menu\n";
c = menu();
while (c != 0) {
if (c == 1) {
addArray();
} else if (c == 2) {
subtractArray();
} else if (c == 3) {
void multiplyArrays();
} else if (c == 4) {
void determArray();
} else if (c == 5) {
void transposeArray();
} else if (c == 6) {
}
c = menu();
}
cout << "Press Enter to Quit. GOOD BYE";
cin >> quit;
return 0;
}
/*
Prints out the specified array.
It's arguments are the actual array and the height/weight
*/
inline void printArray(int** arr, int height, int width) {
for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j) {
std::cout << arr[i][j] << ' ';
}
std::cout << std::endl;
}
}
//Returns an array.
inline int** getArray(int opt) {
if (opt == 0) {
cout << "How many rows and columns should be in the array?\n";
cin >> q >> w;
} else {
q = 3;
w = 3;
}
int** ary = new int*[q];
for (int i = 0; i < q; ++i) {
ary[i] = new int[w];
}
for (row = 0; row < q; row++) {
for (coll = 0; coll < w; coll++) {
cout << "What should the value be for item" << row << "," << coll << "\n";
cin >> ary[row][coll];
}
}
return ary;
}
//Adds arrays
void addArray() {
arr1 = getArray(0);
int h1 = q;
int w1 = w;
arr2 = getArray(0);
int h2 = q;
int w2 = w;
if ((h1 != h2) || (w1 != w2)) {
cout << "Both arrays must be the same size.";
return;
}
for (row = 0; row < q; row++) {
for (coll = 0; coll < w; coll++) {
ans[row][coll] = arr1[row][coll] + arr2[row][coll];
}
}
printArray(ans, q, w);
}
//Subtracts Arrays
void subtractArray() {
arr1 = getArray(0);
int h1 = q;
int w1 = w;
arr2 = getArray(0);
int h2 = q;
int w2 = w;
if ((h1 != h2) || (w1 != w2)) {
cout << "Both arrays must be the same size.";
return;
}
for (row = 0; row < q; row++) {
for (coll = 0; coll < w; coll++) {
ans[row][coll] = arr2[row][coll] - arr1[row][coll];
}
}
printArray(ans, q, w);
}
//Calculate the determinate of an array.
void determArray() {
arr1 = getArray(1);
printArray(arr1, q, w);
//There must be a better/more efficient way to do this using loops.
int determinant = arr1[0][0]*((arr1[1][1] * arr1[2][2]) - (arr1[2][1] * arr1[1][2])) - arr1[0][1]*(arr1[1][0] * arr1[2][2] - arr1[2][0] * arr1[1][2]) + arr1[0][2]*(arr1[1][0] * arr1[2][1] - arr1[2][0] * arr1[1][1]);
printf("\nDeterminant of vector using method 1 is: %d\n", determinant);
}
//Transpose an array.
void transposeArray() {
cout << "IN TRANS";
arr1 = getArray(0);
printArray(arr1, 3, 3);
//Flip the values
for (row = 0; row < q; row++) {
for (coll = 0; coll < w; coll++) {
ans[row][coll] = arr1[coll][row];
}
}
cout << "----------" << endl << "The new vector looks like: \n";
printArray(ans, q, w);
}
/*
Multiply arrays. One option is to just multiply it by a number and the other is to multiply it by another array.
*/
void multiplyArrays() {
arr1 = getArray(0);
int h1 = q;
int w1 = w;
cout << "Do you wish to multiply the first vector by a number(Enter 1), or by a second vector(Enter 2)?";
cin >> qq;
int mu;
//First Option is to multiply it by a single number
if (qq == 1) {
cout << "What number do you wish to multiply the vector by?";
cin >> mu;
for (row = 0; row < q; row++) {
for (coll = 0; coll < w; coll++) {
ans[row][coll] = arr1[row][coll] * mu;
}
}
printArray(ans, h1, w1);
//Multiply two arrays
} else if (qq == 2) {
arr2 = getArray(0);
int h2 = q;
int w2 = w;
int n1 = h1;
int n2 = w2;
int nCommon = n1;
if (n2 == nCommon) {
cout << "Amount of columns for vector 1 must match amount of rows for vector 2";
return;
}
for (int i = 0; i < n1; i++) {
for (int j = 0; j < n2; j++) {
for (int k = 0; k < nCommon; k++) {
ans[i][j] += arr1[i][k] * arr2[k][j];
}
}
}
printArray(ans, n1, n2);
}
}
Upvotes: 0
Views: 450
Reputation: 23624
The problem is that you have not allocated memory for the ans
array, but you are writing to it in the following code:
for (row = 0; row < q; row++) {
for (coll = 0; coll < w; coll++) {
ans[row][coll] = arr2[row][coll] - arr1[row][coll];
}
}
This is why you have segmentation fault.
Try to add a block to allocate memory for ans
at first.
Upvotes: 0
Reputation: 35520
You never allocate memory for ans
. Just like you need to allocate storage for the two input arrays before filling them, you need to allocate storage for the answer.
A segmentation fault is generated when you attempt to write to memory that you do not have access to. In this case, because the ans
array was not initialized, it points to random memory. When you do ans[row][coll] = arr2[row][coll] - arr1[row][coll];
, you get a segfault because ans[row][col]
is pointing somewhere outside your program space.
Upvotes: 5