Two dimensional array - functions - c++

I have to solve a problem with two 2D arrays and calculated things like odds number, sum of even number and addition of the two array. I get multiple errors. Can someone help me?
It is how I define my arrays, and it also says display_odd is not a valid void function. Why?
#define DIM 50
#include <stdio.h>
#include <conio.h>
void display_odd(int[][DIM]);
int display_even_sum(int[][DIM], int[][DIM]);
int display_matrix_sum(int[DIM][DIM], int[DIM][DIM]);
void main(){
int x1, x2, y1, y2, x, y, arr1[DIM][DIM], arr2[DIM][DIM], arr[DIM][DIM];
printf("How large do you want the first matrix to be? ('x y') \n");
scanf("%d %d", &x1, &y1);
for (int i = 0; i < x1; i++){
for (int j = 0; j < y1; j++){
printf("A[%d][%d]= ", i + 1, j + 1);
scanf("%d", &arr1[i][j]);
}
}
printf("How large do you want the second matrix to be? ('x y') \n");
scanf("%d %d", &x2, &y2);
for (int i = 0; i < x2; i++){
for (int j = 0; j < y2; j++){
printf("B[%d][%d]= ", i + 1, j + 1);
scanf("%d", &arr2[i][j]);
}
}
if (x1 > x2)
x = x1;
else
x = x2;
if (y1 > y2)
y = y1;
else
y = y2;
//printf("\nThe odd numbers in matrix A are : \n");
//void display_odd(arr1[DIM][DIM]);
//printf("\nThe odd numbers in matrix B are : \n");
//void display_odd(arr2[DIM][DIM]);
printf("\nThe sum of all even elements is : ");
printf("\nThe sum of the initial matrixes is : \n");
arr = display_matrix_sum(arr1[DIM][DIM] ,arr2[DIM][DIM]);
for (int i = 0; i < DIM; i++){
printf("\n");
for (int j = 0; j < DIM; j++)
printf(" %d", arr[i][j]);
}
_getch(); //Wait for it
}
void display_odd(int arr[][DIM]){
for (int i = 0; i < DIM; i++)
for (int j = 0; j < DIM; j++)
if (arr[i][j] % 2 == 1)
printf("[%d][%d]", i, j);
}
int display_even_sum(int arr1[DIM][DIM],int arr2[DIM][DIM]){
int s = 0;
for (int i = 0; i < DIM; i++)
for (int j = 0; j < DIM; j++)
if (arr1[i][j] % 2 == 0)
s += arr1[i][j];
for (int i = 0; i < DIM; i++)
for (int j = 0; j < DIM; j++)
if (arr2[i][j] % 2 == 0)
s += arr2[i][j];
return(s);
}
int display_matrix_sum(int arr1[][DIM],int arr2[][DIM]){
int arr[DIM][DIM];
for (int i = 0; i < DIM; i++)
for (int j = 0; j < DIM; j++)
arr[i][j] = arr1[i][j] + arr2[i][j];
return(arr[DIM][DIM]);
}

arr = display_matrix_sum(arr1[DIM][DIM] ,arr2[DIM][DIM]);
A C function cannot return an array. You can pass the destination array as an additional argument.
void display_matrix_sum();
…
display_matrix_sum(arr1, arr2, arr);
…
void display_matrix_sum(int arr1[][DIM], int arr2[][DIM], int arr[][DIM])
{
…
// remove this: return(arr[DIM][DIM]);
}

When you declare an array, or when you reference a specific member in an array, you use the square brackets:
int array[2][3];
array[1][0] = 6;
int x = array[1][0]; // x is now 6
when you pass an array as an argument, you simply use the name of the array;
someFunction(array); // passes the array
anotherFunction(array[1][0]); // passes 6;
return array; // returns the array;
return array[1][0]; // returns 6;
It may also help to give the parameters and local variables in your functions different names than the global arrays you define, and to define those global arrays as local arrays in your main function.
The biggest problem is that you don't seem to understand that arrays are just pointers. you can't just pass them around unless they are heap allocated. Each function should be rewritten to show this. For example display_matrix_sum's signature should look like
int** display_matrix_sum(int** A1, int** A2, int rows, int cols);
and should be called by:
int cols = 4; // or whatever
int rows = 4; // or whatever
int** arr1 = new int*[rows]; // arr1 is now any an array of int arrays
int** arr2 = new int*[rows]; // arrays work by pointing to the first element
for(int i = 0; i < rows; i++)
{
arr1[i] = new int[cols]; // each element in arr1 becomes an int array
arr2[i] = new int[cols];
}
/* fill in the values of the arrays */
int** out = display_matrix_sum( arr1, arr2, rows, cols, out);
// output now contains the result of the function
/* when you are done with arr1 and arr2 and out*/
for(int i = 0; i < rows; i++)
{
delete[] arr1[i];
delete[] arr2[i];
delete[] out[i];
}
delete[] arr1;
delete[] arr2;
delete[] out;

Related

Assign pointer to 2d array to an array

So I got a function which creates me 2D array and fill it with test data.
Now I need to assign the pointer to an array
//Fill matrix with test data
int *testArrData(int m, int n){
int arr[n][m];
int* ptr;
ptr = &arr[0][0];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
*((ptr+i*n)+j) = rand()%10;
}
}
return (int *) arr;
}
int arr[m][n];
//Algorithm - transpose
for (int i = 0; i < m; i++){
for (int j = 0; j < n; j++){
arrT[j][i] = arr[i][j];
}
}
Is there any way of doing this?
There are at least four problems with the function.
//Fill matrix with test data
int *testArrData(int m, int n){
int arr[n][m];
int* ptr;
ptr = &arr[0][0];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
*((ptr+i*n)+j) = rand()%10;
}
}
return (int *) arr;
}
First of all you declared a variable length array
int arr[n][m];
Variable length arrays are not a standard C++ feature.
The second problem is that these for loops
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
*((ptr+i*n)+j) = rand()%10;
}
}
are incorrect. It seems you mean
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
*((ptr+i*m)+j) = rand()%10;
}
}
You are returning a pointer to a local array with automatic storage duration that will not be alive after exiting the function. So the returned pointer will be invalid.
And arrays do not have the assignment operator.
Instead use the vector std::vector<std::vector<int>>. For example
std::vector<std::vector<int>> testArrData(int m, int n){
std::vector<std::vector<int>> v( n, std::vector<int>( m ) );
for ( auto &row : v )
{
for ( auto &item : row )
{
item = rand() % 10;
}
}
return v;
}
This is how I would accomplish this. I agree with int ** because it is easy to understand if you dont know how to use vectors. Also, the rand() can cause trouble if you are using the result to index an array. Make sure to use abs(rand() % number) if you don't want negative numbers.
I've updated the answer due to some vital missing code.
// This method creates the overhead / an array of pointers for each matrix
typedef int* matrix_cells;
int **create_row_col_matrix(int num_rows, int num_cols, bool init_rnd)
{
num_rows = min(max(num_rows, 1), 1000); // ensure num_rows = 1 - 1000
num_cols = min(max(num_cols, 1), 1000); // ensure num_cols = 1 - 1000
int *matrix_total = new int[num_rows*num_cols];
// overhead: create an array that points to each row
int **martix_row_col = new matrix_cells[num_rows];
// initialize the row pointers
for (int a = 0; a < num_rows; ++a)
{
// initialize the array of row pointers
matrix_row_col[a] = &matrix_total[num_cols*a];
}
// assign the test data
if (init_rnd)
{
for (int run_y = 0; run_y < num_rows; ++run_y)
{
for (int run_x = 0; run_x < num_cols; ++run_x)
{
matrix_row_col[run_y][run_x] = abs(rand() % 10);
}
}
}
return matrix_row_col;
}
int src_x = 7, dst_x = 11;
int src_y = 11, dst_y = 7;
int **arr_src = create_row_col_matrix(src_y, src_x, true);
int **arr_dst = create_row_col_matrix(dst_y, dst_x, false);
for (int a = 0; a < dst_y; ++a)
{
for (int b = 0; b < dst_x; ++b)
{
arr_dst[a][b] = arr_src[b][a];
}
}
delete matrix_src[0]; // int *matrix_total = new int[src_y*src_x]
delete matrix_src; // int **matrix_row_col = new matrix_cell[src_y]
delete matrix_dst[0]; // int *matrix_total = new int[dst_y*dst_x]
delete matrix_dst; // int **matrix_row_col = new matrix_cell[dst_y]
// the overhead is matrix_src and matrix_dst which are arrays of row pointers
// the row pointers makes it convenient to address the cells as [rown][coln]

C++ multiplying matrices using dynamically allocated memory

I am trying to write a function in C++ that multiplies two matrices A, B which have been dynamically allocated. I am currently trying to get the multiplication code working, then I will attempt to turn it into a function. Right now I am getting an error of sorts; "segmentation fault (core dumped)". I have narrowed it down to the multiplication part of my code but I have no idea what is wrong with it. Can someone help me please? My code is shown below.
#include <iostream>
#include <cassert>
int main()
{
int rowsA = 5; // number of rows
int colsA= 3; // number of coloumns
// dynamically allocating A
double** A;
A = new double* [rowsA];
A[0] = new double [rowsA*colsA];
for (int i = 1; i < rowsA; i++)
{
A[i] = A[i-1] + colsA;
}
// Storing elements of matrix A
for(int i = 0; i < rowsA; ++i)
{
for(int j = 0; j < colsA; ++j)
{
std::cout << "Enter element A" << i + 1 << j + 1 << " : ";
std::cin >> A[i][j];
}
}
int rowsB = 3; // number of rows
int colsB = 5; // number of coloumns
// dynamically allocating B
double** B;
B = new double* [rowsB];
B[0] = new double [rowsB*colsB];
for (int i = 1; i < rowsB; i++)
{
B[i] = B[i-1] + colsB;
}
// Storing elements of matrix B
for(int i = 0; i < rowsB; ++i)
{
for(int j = 0; j < colsB; ++j)
{
std::cout << "Enter element B" << i + 1 << j + 1 << " : ";
std::cin >> B[i][j];
}
}
// checking matrix multiplication qualification
assert(colsA == rowsB);
// dynamically allocating C
double** C;
C = new double* [rowsA];
C[0] = new double [rowsA*colsB];
for (int i = 1; i < rowsA; i++)
{
C[i] = C[i-1] + colsB;
}
// Initializing elements of matrix C to 0
for(int i = 0; i < rowsA; ++i)
{
for(int j = 0; j < colsB; ++j)
{
C[i][j]=0;
}
}
// multiplication
for(int i = 0; i < rowsA; ++i)
{
for(int j = 0; j < colsB; ++j)
{
for(int k = 0; k < colsB; ++k)
{
C[i][j] += A[i][k] * B[k][j];
}
}
}
// Displaying the multiplication of matrices A, B
std::cout<< "Matrix C: " << std::endl;
for(int i = 0; i < rowsA; ++i)
{
for(int j = 0; j < colsB; ++j)
{
std::cout << " " << C[i][j];
if(j == colsB-1)
{
std::cout << std::endl;
}
}
}
// deallocation
delete[] C[0];
delete[] C;
delete[] B[0];
delete[] B;
delete[] A[0];
delete[] A;
}
First, you say you are allocating the matrix properly but I'm not seeing any proof of that. You are allocating an array of pointers and only initializing the first index.. A[0] for example. This is incorrect. You need to allocate EACH ROW.
You have:
double** A;
A = new double* [rowsA];
A[0] = new double [rowsA*colsA]; //Incorrect. You only allocated A[0].
You need to allocate A[0] through A[rowsA - 1]..
Next, your multiplication loop (the inner most loop) is incorrect. It should be:
Iterate ColsA for that inner loop.
You have:
for(int i = 0; i < rowsA; ++i)
{
for(int j = 0; j < colsB; ++j)
{
for(int k = 0; k < colsB; ++k) //ColsB is incorrect. Should be colsA..
{
C[i][j] += A[i][k] * B[k][j]; //Segfaults here due to bad iteration..
}
}
}
The following would be correct:
#include <iostream>
#include <cassert>
double** create_matrix(int rows, int cols)
{
double** mat = new double* [rows]; //Allocate rows.
for (int i = 0; i < rows; ++i)
{
mat[i] = new double[cols](); //Allocate each row and zero initialize..
}
return mat;
}
void destroy_matrix(double** &mat, int rows)
{
if (mat)
{
for (int i = 0; i < rows; ++i)
{
delete[] mat[i]; //delete each row..
}
delete[] mat; //delete the rows..
mat = nullptr;
}
}
int main()
{
int rowsA = 5; // number of rows
int colsA= 3; // number of coloumns
double** matA = create_matrix(rowsA, colsA);
int rowsB = 3; // number of rows
int colsB = 5; // number of coloumns
double** matB = create_matrix(rowsB, colsB);
//Checking matrix multiplication qualification
assert(colsA == rowsB);
double** matC = create_matrix(rowsA, colsB);
//Multiplication
for(int i = 0; i < rowsA; ++i)
{
for(int j = 0; j < colsB; ++j)
{
for(int k = 0; k < colsA; ++k) //ColsA..
{
matC[i][j] += matA[i][k] * matB[k][j];
}
}
}
//Clean up..
destroy_matrix(matA, rowsA);
destroy_matrix(matB, rowsB);
destroy_matrix(matC, rowsA);
}

How to use pointer to pointer for passing matrix?

Passing matrix as a pointer to pointer to function not working.
#include <stdio.h>
void printMatrix(int **matrix, int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
printf("%d ", matrix[i][j]);
printf("\r\n");
}
}
void printM (size_t row, size_t col, int matrix[3][4])
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
printf("%d ", matrix[i][j]);
printf("\r\n");
}
}
int main()
{
int M[3][4];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 4; j++)
M[i][j] = 4*i+j;
printM(3, 4, M);
int *row = *M;
printMatrix(&row, 3, 4); //not working
}
Function printM works, but I would like to know how to use pointer to pointer correctly, thanks for help.
First of all, thank-you for this question. It is a good review of how C does multi-dimensional arrays. Also, it is OK to do double pointers. Remember an array reference is equivalent to a pointer, such as: a[0] and *a both refer to the first element of int a[12]; where *a is the de-referencing of pointer a. And so, &M is a the address of the pointer M when M is declared as int M[3][4];
I modified your code by adding a few comments for clarity and so that it would run in Eclipse using a C compiler from Microsoft, specifically, int declarations where moved out of the for statements. Other than that it is the same as what you originally wrote with a change to the printMatrix declaration and how it is invoked.
Hope this helps, please ask if more questions...
#include <stdio.h>
void printMatrix(int (*matrix)[3][4], int row, int col)
{
int i, j;
// point t so that when de-referenced it is at
// the matrices first element
int *t = (*matrix)[0];
printf("\n");
for (i = 0; i < row; i++)
{
// in C matrices are stored in Row Major form, so
// per K&R just sequentially loop thru (*t)[12]
for (j = 0; j < col; j++) {printf("%d ", *t++);}
printf("\r\n");
}
} // end printMatrix
void printM (size_t row, size_t col, int matrix[3][4])
{
int i, j;
printf("\n");
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++) {printf("%d ", matrix[i][j]);}
// new line for next row
printf("\r\n");
}
}
int main()
{
int i,j;
// define a matrix with 3 rows and 4 columns
int M[3][4];
// fill-in the matrix with values
for (i = 0; i < 3; i++)
for (j = 0; j < 4; j++)
M[i][j] = 4*i + j;
// print the three rows and four columns of M
printM(3, 4, M);
printMatrix(&M, 3, 4); // Also Works
} // end main
void printMatrix(int *matrix, int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
printf("%d ", *(matrix+(i*col)+j);
printf("\r\n");
}
}
Don't do a double pointer.

C++ 2D dynamic array allocation

I have a float** array that contains num_rows rows and num_cols columns. I'd like to determine the number of occurrences of every number between 0-9 columnwise. To do this, I thought of using another 2D array of size [10][num_cols], so that for each column the number corresponding to an element is the number of occurrences of that number in the original table.
Example: if the original table contains 1 2 3 1 1 in the fifth column, then in the second column, the values should be like: 1-> 3, 2 -> 1, 3 -> 1.
I tried using the function as follows, but it gives me a pointer error. I tried using vectors but that too brings no luck.
int ** attribute_count(float * * input, int row_num, int col_num) {
int ** arr_2 = new int * [10];
int * arr = new int[10 * col_num];
int counter = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < col_num; j++) {
arr_2[i][j] = 0;
}
}
for (int i = 0; i < 9; i++) {
for (int j = 0; j < col_num; j++) {
int temp = input[i][j];
arr_2[temp][j]++;
}
}
return arr_2;
}
EDIT:
I tried your suggestions. The new code is:
int** attribute_count(float** input, int row_num, int col_num) {
int** arr_2 = new int* [10];
int* arr = new int[10 * col_num];
int counter = 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < col_num; j++) {
arr_2[i] = new int[col_num];
}
}
for (int i = 0; i < 11; i++) {
for (int j = 0; j < col_num; j++) {
int temp = input[i][j];
arr_2[temp][j]++;
}
}
return arr_2;
}
This still gives me memory errors. The function is being called in the .cpp like this:
int** attr = attribute_count(training_data, 10, num_cols_train);
cout<<attr[5][1];
Any idea what I'm doing wrong even now?
I think your problem is in incorrect allocation of the 2D array. Try
int ** arr_2 = new int* [row_num];
for (int i = 0; i < row_num; i++)
arr_2[i] = new int[col_num];
You've only allocated one dimension of arr_2. You need to loop through and allocate an array of ints on each one to get the 2nd dimension.
EDIT: Also, what's up with arr? You allocate it, never use it, don't return it, and don't deallocate it. That's how we spell memory leak.
arr_2 is defined and allocated as an array of pointers to int, but you don't actually assign/allocate those pointers.
Here's a stab at correcting your code - however I'm not convinced you have rows and columns the right way around...
int ** attribute_count(float ** input, int row_num, int col_num)
{
int ** arr_2 = new int * [10];
for (int i = 0; i < 10; i++)
{
arr_2[i] = new int[col_num];
for(int j = 0 ; j < col_num ; j++)
{
arr_2[i][j] = 0;
}
}
for (int i = 0; i < row_num; i++)
{
for (int j = 0; j < col_num; j++)
{
int temp = input[i][j];
arr_2[temp][j]++;
}
}
return arr_2;
}

Length of multidimensional array

i have a simple program for operations with matrixies, but i have a problem -> i have for example array[3][3] and i need some way how to get the number of dimensions- in this case 3, here is the code:
#include <stdio.h>
#include <stdlib.h>
int **count()
{
printf("Write number of rows and collumns in format ROWS space COLLUMNS");
int i = 0;
int j = 0;
scanf("%i %i", &i, &j);
int **mat1 = (int**)malloc(i*sizeof(int*));
for (int x = 0; x < j;x++){
mat1[x] = (int*)malloc(j*sizeof(int));
}
for (int x = 0; x < i;x++){
for (int y = 0; y < j;y++){
scanf("%i",&mat1[x][y]);
}
}
printf(Write number of rows and collumns in format ROWS space COLLUMNS");
int i2 = 0,j2 = 0;
scanf("%i %i", &i2, &j2);
int **mat2 = (int**)malloc(i2*sizeof(int*));
for (int x2 = 0; x2 < j2;x2++){
mat2[x2] = (int*)malloc(j2*sizeof(int));
}
for (int x2 = 0; x2 < i2;x2++){
for (int y2 = 0; y2 < j2;y2++){
scanf("%i",&mat2[x2][y2]);
}
}
int i3 = i, j3 = j;
int **mat3 = (int**)malloc(i3*sizeof(int*));
for (int x = 0; x < j3;x++){
mat3[x] = (int*)malloc(j3*sizeof(int));
}
for (int x3 = 0; x3 < i3;x3++){
for (int y3 = 0; y3 < j3;y3++){
mat3[x3][y3] = mat1[x3][y3] + mat2[x3][y3];
}
}
return mat3;
}
int writeMatrix(int **mat, int rows, int collumns)
{
int i = rows, j=collumns;
for (int x = 0; x < i;x++){
for (int y = 0; y < j;y++){
printf("%3i ",mat[x][y]);
}
printf("\n");
}
return 0;
}
int main()
{
int **m1 = count();
writeMatrix(m1,x,x);//HERE I NEED TO KNOW NUMBER OF ROWS AND COLLUMNS
free(m1);
}
Here is the code which worked for me in a case of normal array[][] but not in this case -
int y = (sizeof(m1)/sizeof(m1[0][0])) / (sizeof(m1)/sizeof(m1[0]));
You can't have a multidimensional array if you don't knwo statically the size of the first dimension, you'll need a jagged array (an array of arrays), as you did it.
And then you can still get the number of allocated rows and columns. Change the count prototype to:
int** count(int& rows, int& columns)
and in it do these assignments (after you've read the values of i and j):
rows = i;
columns = j;
And call count from main like this:
int rows;
int columns;
int** m1 = count(rows, columns);
Then you can call writeMatrix:
writeMatrix(m1, rows, columns);
BTW, unless you're doing this for educational purposes, you should use std::vector<std::vector<int>> (or some similar array class), not int**.