Nested for loop not looping through second array - c++

How do I get the second array to be properly looped through? It is a simple matrix multiplication operation (using Visual Studio 2019) and arr is being looped through, but arr2 isn't being looped through completely. Only the first 2 elements are being multiplied by all elements of arr.
#include <iostream>
using namespace std;
int main() {
int r1 = 2, c1 = 3, r2 = 3, c2 = 3;
int** arr = new int* [r1];
for (int i = 0; i < c1; i++) {
arr[i] = new int[c1];
}
for (int i = 0; i < r1; i++) {
for (int j = 0; j < c1; j++) {
arr[i][j] = j;
}
}
int** arr2 = new int*[r2];
for (int i = 0; i < c2; i++) {
arr2[i] = new int[c2];
}
for (int i = 0; i < c2; i++) {
for (int j = 0; j < r2; j++) {
arr2[i][j] = j;
}
}
int** arr3 = new int*[r1];
for (int i = 0; i < c2; i++) {
arr3[i] = new int[c2];
}
for (int i = 0; i < r1; i++) {
for (int j = 0; j < c2; j++) {
arr3[i][j] = 0;
}
}
for (int i = 0; i < r1; i++) {
for (int j = 0; j < c2; j++) {
for (int g = 0; g < c1; g++) {
arr3[i][j] += arr[i][g] * arr2[g][j];
cout << "[" << i << "][" << g << "] " << arr[i][g] << "\tX\t" << "[" << g << "][" << j << "] " << arr2[g][j] << " => " << arr3[i][j] << endl;
}
}
}
cout << "\n" << endl;
for (int i = 0; i < r1; i++) {
for (int j = 0; j < c2; j++) {
cout << "New Array Element: [" << i << "][" << j << "] => " << arr3[i][j] << endl;
}
}
return 0;
}

You make the same basic mistake in all of your loops -- that mistake being that you are not iterating over the rows correctly.
You are using the column count when you should be using the row count:
int** arr = new int* [r1];
for (int i = 0; i < c1; i++) { // <-- This should be i < r1, not i < c1;
arr[i] = new int[c1];
}
Second, you could have written a function to lessen the chance of error, and also have a better chance of finding bugs like this:
int **createArray(int rows, int cols)
{
int** arr = new int* [rows];
for (int i = 0; i < rows; i++) {
arr[i] = new int[cols];
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
arr[i][j] = j;
}
}
return arr;
}
int main()
{
int r1 = 2, c1 = 3, r2 = 3, c2 = 3;
int** arr = createArray(r1, c1);
int** arr2 = createArray(r2,c2);
int** arr3 = createArray(r1,c2);
//...
}
Now the creation code is not repeated over and over again, plus the issue of using the wrong variables becomes minimized, if not eliminated.
Having said this, this way of creating 2D arrays is one of the worst ways of doing this. Right now, your code has memory leaks (it still is considered a leak, even though the program will terminate -- memory tools such as valgrind and others would indicate the errors as soon as your program exits).
Ideally, you would use a container class such as std::vector<int> to handle the dynamic memory management automatically.
But even if this is an exercise where you must use int**, it is still a very bad way of creating two-dimensional arrays under those constraints. Here is an answer that goes in detail about this issue, why it's bad, and how it can be alleviated.

Related

Static array and Dynamic array in a function

I have a question as below C++ code.
this is the code(No function) that can successful execute.
#include <iostream>
using namespace std;
int main()
{
int size_3 = 3;
//arr1 is a static array
int arr1[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
//arr2 is a dynamic array
int** arr2 = new int* [size_3];
for (int i = 0; i < size_3; i++) {
arr2[i] = new int[size_3];
}
int val = 9;
for (int i = 0; i < size_3; i++) {
for (int j = 0; j < size_3; j++) {
arr2[i][j] = val--;
}
}
cout << "Elements in matrix 1: " << endl;
for (int i = 0; i < size_3; i++) {
for (int j = 0; j < size_3; j++) {
cout << arr1[i][j] << " ";
}
cout << endl;
}
cout << endl;
cout << "Elements in matrix 2: " << endl;
for (int i = 0; i < size_3; i++) {
for (int j = 0; j < size_3; j++) {
cout << arr2[i][j] << " ";
}
cout << endl;
}
cout << endl;
int** prod_arr = new int* [size_3];
for (int i = 0; i < size_3; i++) {
prod_arr[i] = new int[size_3];
}
for (int i = 0; i < size_3; i++) {
for (int j = 0; j < size_3; j++) {
prod_arr[i][j] = 0;
for (int k = 0; k < size_3; k++) {
prod_arr[i][j] += arr1[i][k] * arr2[k][j];
}
}
}
cout << "Elements in the product of 2 matrices: " << endl;
for (int i = 0; i < size_3; i++) {
for (int j = 0; j < size_3; j++) {
cout << prod_arr[i][j] << " ";
}
cout << endl;
}
}
However, I am gonna to use the function for the multiplication of the 2 matrices.
how could I move it to function, since the first array is static array, the second array is dynamic array.
I have try different way to use pointer , pass-by reference in the function, but still can't work.
My invalid code as below.
#include <iostream>
using namespace std;
int** function(int farr1, int farr2, int size3) {
int** prod_arr = new int* [size3];
for (int i = 0; i < size3; i++) {
prod_arr[i] = new int[size3];
}
for (int i = 0; i < size3; i++) {
for (int j = 0; j < size3; j++) {
prod_arr[i][j] = 0;
for (int k = 0; k < size3; k++) {
prod_arr[i][j] += farr1[i][k] * farr2[k][j];
}
return prod_arr[i][j];
}
}
}
int main()
{
int size_3 = 3;
//arr1 is a static array
int arr1[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
//arr2 is a dynamic array
int** arr2 = new int* [size_3];
for (int i = 0; i < size_3; i++) {
arr2[i] = new int[size_3];
}
int val = 9;
for (int i = 0; i < size_3; i++) {
for (int j = 0; j < size_3; j++) {
arr2[i][j] = val--;
}
}
cout << "Elements in matrix 1: " << endl;
for (int i = 0; i < size_3; i++) {
for (int j = 0; j < size_3; j++) {
cout << arr1[i][j] << " ";
}
cout << endl;
}
cout << endl;
cout << "Elements in matrix 2: " << endl;
for (int i = 0; i < size_3; i++) {
for (int j = 0; j < size_3; j++) {
cout << arr2[i][j] << " ";
}
cout << endl;
}
cout << endl;
int** prod_arr = function(farr1, farr2, size_q3);
cout << "Elements in the product of 2 matrices: " << endl;
for (int i = 0; i < size_3; i++) {
for (int j = 0; j < size_3; j++) {
cout << prod_arr[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
I want to use the function to execute the code.
I got 2 array, one is static and another is dynamic,
How to use pointer and pass to function with this different arrays.
Thanks a lot for your help.
Some C++ array examples to get you started :
A 2D dynamically array can be modeled as std::vector<std::vector<int>>
#include <array> // static array
#include <vector> // dynamic array, can resize at runtime
#include <iostream>
// https://en.cppreference.com/w/cpp/container/array
// accept a modifiable static array (content can be changed
// the & means by reference, the array will not get copied
// https://isocpp.org/wiki/faq/references
void func1(std::array<int, 4>& values)
{
values[2] = 3;
}
// array cannot be modified in body of func2 only used : const
void func2(const std::array<int, 4>& values)
{
std::cout << values[2] << "\n";
}
// https://en.cppreference.com/w/cpp/container/vector
// return a dynamically allocated array of integers
// it will have a size of 5 when returned
std::vector<int> get_values()
{
return std::vector<int>{1, 2, 3, 4, 5};
}
int main()
{
auto values = get_values();
values.push_back(6); // add another value
// https://en.cppreference.com/w/cpp/language/range-for
// prefer to use those if you don't need indices
// (which is not as often as you think)
for (const int value : values)
{
std::cout << value << " ";
}
return 0;
}

What happens with the dynamic memory allocation, of a matrix with different size of columns on each line?

I'm trying to create a matrix in C++, having a shape of a triangle like this :
n = number of lines;
If i input n = 4, for example, my matrix should look like this :
1
23
456
78910
I've managed to do the following code :
int n;
cout << "Introduceti n: ";
cin >> n;
int** a = new int*[n];
for (int i = 0; i < n; i++) {
a[i] = new int[i+1];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < i+1; j++) {
*(*(a + i) + j) = (i * i + i) / 2 + j +1;
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < i+1; j++) {
cout << *(*(a + i) + j) << "|";
}
cout << endl;
}
The question is : why can i access a[0][1] and it shows me a value, if i instructed my pointer to stop initializing at a[0][0] ?
You can access memory, regardless of it being initialized or allocated.
It is up to you to code avoiding those likely unwanted events, or having mechanisms in place to detect them.
So,
why can i access a[0][1]...
As said above
... and it shows me a value, ...
Because every bit in memory has some value.
Try code below, and you will probably understand what you are doing.
The least memory you can take is by ensuring you have contiguous allocation. So you would rather allocate storage in a linear array for (n*(n+1)/2) ints (the size of your triangular matrix), and then simply define functions/macros for accessing element (i,j). It may take not more than 20 lines of code... if you want to work fail-safe, you can include a few checks for a couple more lines.
#include <iostream>
using namespace std;
int main() {
int n;
cout << "Introduceti n: ";
cin >> n;
int **a = new int*[n];
for (int i = 0; i < n; i++) {
a[i] = new int[i + 1];
}
cout << "Size of int is " << sizeof(int) << endl;
for (int i = 0; i < n; i++) {
for (int j = 0; j < i + 1; j++) {
*(*(a + i) + j) = (i * i + i) / 2 + j + 1;
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < i + 1; j++) {
cout << *(*(a + i) + j) << "|";
}
cout << endl;
}
cout << "a[0][0] #" << &(a[0][0]) << "=" << a[0][0] << endl;
cout << "a[0][1] #" << &(a[0][1]) << "=" << a[0][1] << endl;
return 1;
}

dynamically allocating memory to matrices

I am trying to convert an array to a matrix, so I dynamically allocated memory to the matrix, but I'm getting an error:
CRT detected that the application wrote to memory after end of heap buffer
int main() {
float a[9] = { 1, 3, 5, 6,4,6,5,6,8};
int b = sizeof(a)/sizeof(a[0]);
int r = sqrt(b) - 1;
float **A_mat = new float*[r];
//A_mat = ;
for (int i = 0; i <= r; i++)
A_mat[i] = new float[r];
for (int j = 0; j <= r; j++) {
for (int i = 0; i <= r; i++) {
A_mat[j][i] = a[i + j * (r+1)];
}
}
cout << "a[0,0] is " << A_mat[0][0] << endl;
cout << "a[0,2] is " << A_mat[0][2] << endl;
cout << "a[1,0] is " << A_mat[1][0] << endl;
cout << "a[2,0] is " << A_mat[2][0] << endl;
for (int i = 0; i <= r; i++) {
delete[] A_mat[i];
}
delete[] A_mat;
system("pause");
}
Your code has two major issues:
Issue 1:
float **A_mat = new float*[r]; // allocating memory for 2 rows because r = sqrt(9) - 1 => r = 2
for (int i = 0; i <= r; i++)
A_mat[i] = new float[r]; // Usage of A_mat[r] for r = 2 is out of bounds. Also, memory is allocated for 2 columns.
Issue 2:
for (int j = 0; j <= r; j++) {
for (int i = 0; i <= r; i++) {
A_mat[j][i] = a[i + j * (r+1)]; // accessing indices (0, 2), (1, 2), (2, 0), (2, 1), (2, 2) are out of bounds
}
}
Instead, you should allocate (r + 1) size memory. Like this:
int main() {
float a[9] = { 1, 3, 5, 6,4,6,5,6,8};
int b = sizeof(a)/sizeof(a[0]);
int r = sqrt(b) - 1;
float **A_mat = new float*[r + 1];
//A_mat = ;
for (int i = 0; i <= r; i++)
A_mat[i] = new float[r + 1];
for (int j = 0; j <= r; j++) {
for (int i = 0; i <= r; i++) {
A_mat[j][i] = a[i + j * (r+1)];
}
}
cout << "a[0,0] is " << A_mat[0][0] << endl;
cout << "a[0,2] is " << A_mat[0][2] << endl;
cout << "a[1,0] is " << A_mat[1][0] << endl;
cout << "a[2,0] is " << A_mat[2][0] << endl;
for (int i = 0; i <= r; i++) {
delete[] A_mat[i];
}
delete[] A_mat;
system("pause");
}
Suggestions:
1) Never use raw pointers. Always look for safer alternatives. In this case, you should go for std::vector.
2) Never use naked new. It is generally the major source of Memory leaks. Though currently, its not the case for you. But it might become an issue in the future.
3) Always remember that array starts from 0-indexing in C++.
You have problem with for loop. The index is from 0 to (r-1). But your for loop from 0 to r. It made out of bound of your array.
1> So please replace this for loop
for (int i = 0; i <= r; i++)
by
for (int i = 0; i < r; i++)
2> And replace this statements
for (int j = 0; j <= r; j++) {
for (int i = 0; i <= r; i++) {
A_mat[j][i] = a[i + j * (r+1)];
}
}
by
for (int j = 0; j < r; j++) {
for (int i = 0; i < r; i++) {
A_mat[j][i] = a[i + j * r];
}
}

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

Dynamic Multidimensional array in C++

I made Matrix Multiplication program in c++ using dynamic Multidimensional arrays.
problem is when i enter test values
matrix A = row1{ 1 } , row2 { 2 } matrix B = row1 {1 ,2 , 3} , it stops working at the loop where user
inputs values of first array , i found it using debugging. but program works fine when i enter
matrix A = row1{ 1 , 2 } , row2 { 3 , 4 } matrix B = row1 {5 , 6 } , row2 {7 , 8}
i want this program to be a general program that can multiply all matrixs
#include <iostream>
using namespace std;
class Lab_02
{
public:
void Product(){
int a1Rows, a1Columns;
int a2Rows, a2Columns;
cout << "Plz Enter the no. of rows for Array 1 :";
cin >> a1Rows;
cout << "Plz Enter the no. of columns for Array 1 :";
cin >> a1Columns;
cout << "Plz Enter the no. of rows for Array 2 :";
cin >> a2Rows;
cout << "Plz Enter the no. of columns for Array 2 :";
cin >> a2Columns;
int **dynamicArray = 0;
int **dynamicArray2 = 0;
int **dynamicArray3 = 0;
cout << endl;
for (int i = 0; i < a1Rows; i++)
{
dynamicArray3 = new int *[a1Rows];
}
for (int i = 0; i < a2Columns; i++)
{
dynamicArray3[i] = new int[a2Columns];
}
// memory allocated for elements of rows.
for (int i = 0; i < a1Rows; i++)
{
dynamicArray = new int *[a1Rows];
}
// memory allocated for elements of each column.
for (int i = 0; i < a1Columns; i++)
{
dynamicArray[i] = new int[a1Columns];
}
// memory allocated for elements of rows.
for (int i = 0; i < a2Rows; i++)
{
dynamicArray2 = new int *[a2Rows];
}
// memory allocated for elements of each column.
for (int i = 0; i < a2Columns; i++)
{
dynamicArray2[i] = new int[a2Columns];
}
cout << "enter the values or array 1 \n";
for (int i = 0; i < a1Rows; i++)
{
for (int j = 0; j < a1Columns; j++)
{
cout << "array[" << i << "][" << j << "]\t";
cin >> dynamicArray[i][j];
}
}
cout << "enter the values or array 2 :\n";
for (int i = 0; i < a2Rows; i++)
{
for (int j = 0; j < a2Columns; j++)
{
cout << "array[" << i << "][" << j << "]\t";
cin >> dynamicArray2[i][j];
}
}
int sum;
for (int i = 0; i < a1Rows; i++)
{
for (int j = 0; j < a1Columns ; j++)
{
sum = 0;
for (int k = 0; k < a2Columns ; k++)
{
sum = sum + (dynamicArray[i][k] * dynamicArray2[k][j]);
}
dynamicArray3[i][j] = sum;
}
}
cout <<"Result" << endl << endl;
for (int i = 0; i < a1Rows; i++)
{
for (int j = 0; j < a2Columns; j++)
{
cout << dynamicArray3[i][j] << "\t";
}
cout << endl;
}
}
};
void main(void)
{
Lab_02 object;
object.Product();
}
Your memory allocations for the matricies are the issue.
Change them to something like the following
// memory allocated for elements of rows.
dynamicArray = new int *[a1Rows];
// memory allocated for elements of each column.
for (int i = 0; i < a1Rows; i++)
{
dynamicArray[i] = new int[a1Columns];
}
You need to allocate one array of array for the rows and then you need to loop over the rows and allocate the columns.
The issue with the code is that you are not supposed to allocate the "rows" in a loop. All you need is one allocation for the rows, and then loop to allocate the data for each row.
So for example, instead of this:
for (int i = 0; i < a1Rows; i++)
{
dynamicArray = new int *[a1Rows];
}
// memory allocated for elements of each column.
for (int i = 0; i < a1Columns; i++)
{
dynamicArray[i] = new int[a1Columns];
}
The correct way would be this:
dynamicArray = new int *[a1Rows];
for (int i = 0; i < a1Columns; i++)
{
dynamicArray[i] = new int[a1Columns];
}
You made the same mistake for each of the loops.
Also, some points:
You failed to deallocate the memory that was allocated.
If you used std::vector, then things become much easier.
You need to check if the matrices are multiplyable before performing the sum loop. By multiplyable meaning that the number of columns and rows of matrix A and B satisfy the requirements for multiplication of A and B.
for (int i = 0; i < a1Rows; i++)
{
for (int j = 0; j < a1Columns; j++)
{
sum = 0;
for (int k = 0; k < a2Columns; k++)
sum = sum + (dynamicArray[i][k] * dynamicArray2[k][j]);
dynamicArray3[i][j] = sum;
}
}
This loop will go haywire if the dynamicArray1 and dynamicArray2 do not have the requisite number of columns and rows before multiplying.
First, the following test should be done before multiplying:
if (a1Columns != a2Rows)
return;
Second, your k loop is wrong. It should be this:
for (int k = 0; k < a2Rows; k++)
sum = sum + (dynamicArray[i][k] * dynamicArray2[k][j]);
dynamicArray3[i][j] = sum;