Segmentation fault while passing multidimensional arrays, c++ - c++

I'm pretty new to coding in c++ so I apologize if this question has a very apparent simple answer. I'm trying to create a matrix of random numbers from -1 to 1. These are the two functions I am using:
#include <iostream>
#include "matrix_fill_random.cpp"
using namespace std;
int main(int argc, int argv[]){
int n1, n2, n3;
if (argc != 4) {
cerr << "This program requires 3 argument!" <<endl;
return 1;
}
else{
n1 = argv[1];
n2 = argv[2];
n3 = argv[3];
double** a;
matrix_fill_random(n1, n2, a);
return 0;
}
}
and
#include <iostream>
using namespace std;
int matrix_fill_random(int n1, int n2, double** a){
for (int i=0; i<n1; i++){
for (int j=0; j<n2; j++){
double num = rand() % 2 - 1;
a[i][j]=num;
}
}
return 0;
}
Ultimately I'm trying to create two matrices and then multiply them together so n1, n2, and n3 represent the rows and columns of two matrices, but that isn't all too important right now. I think the error might be in how I declare my variables or pass them to other functions but I'm not entirely sure.
I feel like if I can understand the principle of creating one of the matrices then that would translate to the other functions I need to use.

double** a;
You haven't allocated memory for the pointer, so you're getting Undefined Behavior each time you dereference it using operator [].
You should allocate a once before passing it through the function...
double** a = new double*[n1];
and once more inside the for loop of the function:
for (int i = 0; i < n1; i++)
{
a[i] = new double[n2];
for (int j = 0; j < n2; j++)
{
double num = rand() % 2 - 1;
a[i][j] = num;
}
}
But don't forget to delete[] the pointer once you're done using it. You should delete the other pointers allocated inside the for loop as well.
Of course, this can all be avoided by using std::vector. Here is your program fitted with the Standard Library:
std::vector<std::vector<double>> a(n1, std::vector<double>(n2));
int matrix_fill_random(std::vector<std::vector<double>> a)
{
for (int i = 0; i < a.size(); ++i)
{
for (int j = 0; j < a[i].size(); ++j)
{
double num = rand() % 2 - 1;
a[i][j] = num;
}
}
return 0;
}

Allocate the memory for a. You haven't allocate the memory for a. Chane the statement double** a; to
double** a = new double[n1];
and change the loop as follows
for (int i = 0; i < n1; i++)
{
//Every row will be of size = number of columns.
a[i] = new double[n2];
for (int j = 0; j < n2; j++)
{
double num = rand() % 2 - 1;
a[i][j] = num;
}
}

double** a;
matrix_fill_random(n1, n2, a);
passes uninitialized pointer a to the function, which tries to initialize elements of two-dimensional array:
a[i][j]=num;
which invokes an undefined behavior. The simplest solution would be to allocate a single block of memory that will be big enough to hold the matrix:
double* a = new double[rows * cols];
matrix_fill_random(n1, n2, a);
delete[] a;
a = NULL;
...
// accessing element a[i][j] in the function's body:
a[i*cols + j] = num;
but most reasonable solution would be using std::vector instead of C-style arrays.

You need to allocate memory to a before passing it to matrix_fill_random().
double** a = new double[n1];
Since you're using C++ though, you should consider using a vector or other template container.

Related

Passing 2D array to a function without using vectors [duplicate]

This question already has answers here:
Passing a 2D array to a C++ function
(17 answers)
Closed 1 year ago.
I am writing a program to print the sum of the elements of a user entered square matrix in the form of a 2D array without using vector. However I am getting 2 errors:
Error 1: error:array has incomplete element type 'int []'.
Error 2:
error: expected expression cout<<sumarr(arr[][]
This is my program:
int sumarr(int arr[][]) // ERROR 1
{
// finging no. pf rows(or coloums) of the square matrix
int n = sizeof(arr) / (2 * sizeof(int));
int sum = 0;
for (int i = 0; i < n; i++) // calculating sum of elements
{
for (int j = 0; j < n; j++)
{
sum += arr[i][j];
}
}
}
int main()
{
int n; // No. of rows(or coloumns) of the square matrix
cin >> n;
int arr[n][n];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++) // inputting array elements
{
cin >> arr[i][j];
}
}
cout << sumarr(arr[][]); // ERROR 2
return 0;
}
Can someone suggest why I am getting these errors and how to resolve them?
In the function parameter (Error 1) you'll need to specify at least the last dimension of the array:
int sumarr(int arr[][SIZE]){ /*...*/}
In the call to the function you need to use the array name only, no dereferencing necessary (Error 2):
cout << sumarr(arr);
The problem then becomes the fact that Variable Length Arrays are not allowed in C++, so you probably should rethink the possibility of using vectors for this task.
Another thing worth mentioning is that sizeof(arr) inside the function will not render you the size of the array but the size of the pointer, which is what arr becomes when passed as an argument.
Alternatively you can manually allocate memory for the array, it could look more or less like this:
Live sample
#include <iostream>
#include <cassert>
// since sizeof arr can't work you should pass the size as argument
int sumarr(int **arr, int n)
{
assert(n > 0 && n < 1000); // confirm that n is valid, > 0 and a suitable upper limit
int sum = 0;
for (int i = 0; i < n; i++) //calculating sum of elements
{
for (int j = 0; j < n; j++)
{
// input and sum in the same loop will save you a O(N^2) operation
std::cin >> arr[i][j];
sum += arr[i][j];
}
}
return sum;
}
int main()
{
int n; //No. of rows(or columns) of the square matrix
std::cin >> n;
// memory allocation for 2D array
int **arr = new int *[n];
for (int i = 0; i < n; i++)
{
arr[i] = new int[n];
}
//end
int sum = sumarr(arr, n); // passing array and size
std::cout << "Sum: " << sum;
// freeing memory after use
for (int i = 0; i < n; i++)
{
delete [] arr[i];
}
delete [] arr;
//end
}

Function that accepts a 2D array, multiplies it by an integer, and returns the new 2D array in C++?

say I have a 3x4 array with integer elements, I want to pass this array to a function that then takes all of the elements and multiplies them by some integer 'b' then returns this new array, how would I go about it? this is what I have currently
#include <iostream>
#include <math.h>
using namespace std;
// my function for multiplying arrays by some integer b
int* multarray(int (*a)[4], int b)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
*(*(a+i)+j) *= b;
}
}
return *a;
}
int main()
{
// creating an array to test, values go from 1-12
int arr [3][4];
int k = 1;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
arr[i][j] = k;
k++;
}
}
// trying to setup new 'array' as a product of the test array
int *newarray;
newarray = multarray(arr,3);
// printing values (works with *(newarray+i) only)
for (int i = 0; i < 3; i++)
{
for (int j=0; j<4; j++)
{
cout << *(*(newarray+i)+j);
}
}
return 0;
}
this works if I don't include the j part when printing all my values but as it is now, tells me I have an error: invalid type argument of unary '*' (have 'int')
Your function is not returning a new array, it's modifying an existing array. So (assuming this is not a problem for you) you should just change the return type to void.
void multarray(int (*a)[4], int b)
{
...
}
Then
multarray(arr,3);
for (int i = 0; i < 3; i++)
{
for (int j=0; j<4; j++)
{
cout << *(*(arr+i)+j);
}
}
If you really do want a function that returns a new array, then that's a whole different (and much more complicated) problem . Apart from anything else it's, strictly speaking, impossible to return an array in C++.

multiplying two arrays of different dimensions in c++

for my assignment I have to multiply two matrices together to create a new one. I will then sort the new one from an inherited class. My question is what is the format to multiply two arrays of different dimensions my first one a1d is 5 integers. My other one a2d is a 5x10 array. What is the correct way to multiply these together being that they are different sizes and dimensions. Do I multiply a1d by every row of a2d? I am going to output the products to a 1 dimensional array so that sorting is easier. I have drawn out the two arrays as tables to help me visualize it. I will attach the short code I have and my illustration. This is in C++.
#pragma once
#include<ctime>
#include<iostream>
#include<cmath>
using namespace std;
class matrices
{
private:
int* a1d[5]; // Old Code:int* a1d = new int[5];
int** a2d = new int* [5];
public:
int* matrix;
matrices();
~matrices();
int* filla1d();
int* filla2d();
int* multiply();
};
int* matrices::filla1d() {
for (int i = 0; i < 5; i++) {
a1d[i] = new int;
}
for (int i = 0; i < 5; i++) {
*a1d[i] = rand() % 10 + 1;
}
return *a1d;
}
int* matrices::filla2d() {
for (int i = 0; i < 5; i++) {
a2d[i] = new int[10];
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 10; j++) {
a2d[i][j] = rand() % 10 + 1;
cout << a2d[i][j] << endl;
}
}
return *a2d;
}
int* matrices::multiply() {
}
it is required that I only use pointer type variables and pointer returning functions, though that doesn't change too much. I don't know how they should be multiplied, and because of that, I am not sure how many values will be generated from the multiplication for the size of the new array. Thanks in advance!
Here is what I have designed to multiply them together. I have changed how my pointer arrays are allocated. My problem now is that it tells me that "expression must have arithmetic or unscoped enum type". Where I have matrix[i] =(a1d[index1] * a2d[index1][index2]); I thought maybe a1d needed to be a pointer type but it gives me the error where it can't convert from int* to int.
Also, when I debug, my a1d and matrix arrays allocate perfectly and show the correct number of data slots when moused over. However, a2d only shows one pointer which points to 5 in this case. I followed the syntax I have seen online for an array of pointers to create a 2d array.
int* matrices::filla1d() {
for (int i = 0; i < 5; i++) {
a1d[i] = new int;
}
for (int i = 0; i < 5; i++) {
*a1d[i] = rand() % 10 + 1;
}
return *a1d;
}
int* matrices::filla2d() {
for (int i = 0; i < 5; i++) {
a2d[i] = new int[10];
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 10; j++) {
a2d[i][j] = rand() % 10 + 1;
}
}
return *a2d;
}
int* matrices::multiply() {
for (int i = 0; i < 50; i++) {
matrix[i] = new int;
}
int index1 = 0;
int index2 = 0;
for (int i = 0; i < 50; i++) {
matrix[i] = (a1d[index1] * a2d[index1][index2]);
index1++;
index2++;
}
return *matrix;
}
class matrices
{
private:
int* a1d[5];
int** a2d = new int*[5];
public:
int* matrix[50];
matrices();
~matrices();
int* filla1d();
int* filla2d();
int* multiply();
};
Edit 2:
I changed the line to fill up the new matrix to say
*matrix[i] = a2d[index1][index2] * *a1d[index1];
Now I get an access violation error on this line. I have matrix allocated the same way I have a1d allocated, what can cause my access violation?

Linear Recursion reverse the array

Can not figure out why my recursion function does not work?
#include <iostream>
using namespace std;
int ReverseArray(int* A, int i, int j);
int main()
{
int j = 10;
int i = 0;
int *b = new int[j];
for (int i = 0; i <= 10; i++)
b[i] = i;
for (int i = 0; i <= 10; i++) //just to compare the old and new array
cout << b[i] << endl; //just to compare the
for(int i = 0; i <= j; i++)
cout << ReverseArray(b,i,j) << endl;
system("pause");
return 0;
}
int ReverseArray(int* A, int i, int j)
{
if (i <= j)
{
swap(A[i], A[j]);
ReverseArray(A, i + 1, j - 1);
}
return A[i];
This should return
10,9,8....
but it returns
10,0,9,1...
I don't get why its happening
You have a double loop, once here:
for(int i = 0; i <= j; i++)
cout << ReverseArray(b,i,j) << endl;
and once here:
ReverseArray(A, i + 1, j - 1);
Calling a function recursively is equivalent to looping over it. To reverse a list, you only need to loop over it once, and what you've done is the equivalent of a doubly-nested loop. So let's get rid of
for(int i = 0; i <= j; i++)
and change
cout << ReverseArray(b,i,j) << endl;
to just
ReverseArray(b,i,j);
Then you are only reversing b, nothing else. To print, just loop from 0 to 10 and print each element.
Also, unrelated, but keep in mind that the code as you have it right now touches memory that has not been allocated to the heap.
int *b = new int[j];
creates j (here, 10) ints, at the physical memory locations b, b + 1, b + 2, ..., b + 9. b[i] then gets the memory held at b + i, that is, it gets *(b + i). Several of your loops try to do things with b[10], and there has not been enough memory allocated for it. This will result in undefined behaviour (i.e. many different things can happen depending on your compiler and the state of your computer). With 'system("pause");' removed (which shouldn't affect code execution) on my machine, this gave me a memory allocation for that reason.
Solution here is to either have
int *b = new int[j+1];
or replace all your <= signs with <.

returning a two dimensional array from a function in c++ [duplicate]

This question already has answers here:
Returning multidimensional array from function
(7 answers)
Closed 9 years ago.
I want to use a two dimensional int array which is returned from a function
how should I define the function return value ?
I used int** but the compiler gave error:
int** tableCreator(){
int** table=new int[10][10];
for(int xxx=1;xxx<10;xxx++){
for(int yyy=1;yyy<10;yyy++){
table[xxx][yyy]=xxx*yyy;
}
}
return(table); //Here:cannot convert from 'int (*)[10]' to 'int **'
}
Try this:
#include <cstdio>
#include <cstdlib>
int** createTable(int rows, int columns){
int** table = new int*[rows];
for(int i = 0; i < rows; i++) {
table[i] = new int[columns];
for(int j = 0; j < columns; j++){ table[i][j] = (i+j); }// sample set value;
}
return table;
}
void freeTable(int** table, int rows){
if(table){
for(int i = 0; i < rows; i++){ if(table[i]){ delete[] table[i]; } }
delete[] table;
}
}
void printTable(int** table, int rows, int columns){
for(int i = 0; i < rows; i++){
for(int j = 0; j < columns; j++){
printf("(%d,%d) -> %d\n", i, j, table[i][j]);
}
}
}
int main(int argc, char** argv){
int** table = createTable(10, 10);
printTable(table, 10, 10);
freeTable(table, 10);
return 0;
}
You need the second loop to allocate a 2-d array in C and similar operation to free it. a two-D array is in essence an array of arrays so can be expressed as a pointer array. the loop initializes the arrays pointed to the pointers.
Clarifying as per conversation with #Eric Postpischil below: changed createTable to take row/column count for truly dynamic allocation.
int** table=new int[10][10];
this is wrong. you cannot allocate space for 2D dynamic array in this way in C/C++.
Meanwhile, you declared array size as 10, so indices are from 0-9, but you are trying to assign values to index 10 in your nested for loops, which is not right too.
You may do the following for allocation:
int** table = new int*[10];
for (int i = 0; i < 10; ++i)
{
table[i] = new int[10];
}
Usually, the type used to point to an array is a pointer to an element of the array. Since a two-dimensional array of int is an array of array of int, you want a pointer to array of int. The C++ syntax for this type is int (*)[N], for some dimension N. This code demonstrates:
#define N 10
int (*tableCreator())[N]
{
int (*table)[N] = new int[N][N];
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
table[i][j] = i*j;
return table;
}
#include <iostream>
int main()
{
int (*t)[N] = tableCreator();
for (int i = 0; i < N; ++i)
{
for (int j = 0; j < N; ++j)
std::cout << t[i][j] << ' ';
std::cout << '\n';
}
delete [] t;
return 0;
}
I. Arrays are not pointers.
II. Why not vector<vector<int> >?
III. If not, then:
typedef int Int10Array[10];
Int10Array *arr = new Int10Array[10];
IV. Why write past the bounds? Do you want explicit nasal demons?
for(int xxx = 0; xxx < 10; xxx++)
^^^ ^^^^