Converting 2d array C code to malloc - c

I made a program that adds two matrices and displays their sum with a max dimension of 100.
/* This program asks the user for 2 matrices called A and B, as integers,
and displays their sum, C. The max dimension of each matrix is 100. */
#include <stdio.h>
// Construct function
void construct()
{
int m, n, i, j; // Variables
int first[100][100], second[100][100], sum[100][100]; // Matrices variables
printf("Please enter the number of rows: ");
scanf("%d", &m);
printf("Please enter the number of columns: ");
scanf("%d", &n);
// User enters m x n amount whole numbers for the Matrix A
printf("Enter Matrix A\n");
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%d", &first[i][j]);
// User enters m x n amount whole numbers for the Matrix B
printf("Enter Matrix B\n");
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%d", &second[i][j]);
// Adds the sum of Matrix A and Matrix B
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
sum[i][j] = first[i][j] + second[i][j];
// Display the sum of Matrix A and Matrix B
printf("A + B =\n");
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
printf("%d ", sum[i][j]);
printf("\n"); // Prints new line
}
return ;
}
// Main Function
int main()
{
construct(); // Calls construct function
return 0;
}
Now I need to change it so there is no max size for each matrix.
So I need to use malloc to create my arrays.
So I cant use int A[rows][cols].
This is what I did to covert arrays to malloc. It compiles but it crashes after I entered all the integers. Need help.
/* This program asks the user for 2 matrices called A and B, as integers,
and displays their sum, C. The max dimension of each matrix is 100. */
#include <stdio.h>
#include <stdlib.h>
// Construct function
void construct()
{
int m, n, i, j; // Variables
int *first = NULL;
int *second = NULL;
int *sum = NULL; // Matrices variables
printf("Please enter the number of rows: ");
scanf("%d", &m);
printf("Please enter the number of columns: ");
scanf("%d", &n);
first = (int*)malloc(m * sizeof(int));
second = (int*)malloc(n * sizeof(int));
sum = (int*)malloc(m * n * sizeof(int));
// User enters m x n amount whole numbers for the Matrix A
printf("Enter Matrix A\n");
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%d", &first);
// User enters m x n amount whole numbers for the Matrix B
printf("Enter Matrix B\n");
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%d", &second);
// Adds the sum of Matrix A and Matrix B
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
sum = *first + *second;
// Display the sum of Matrix A and Matrix B
printf("A + B =\n");
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
printf("%d ", sum);
printf("\n");
}
return ;
}
// Main Function
int main()
{
construct(); // Calls construct function
return 0;
}

First of all, you don't need to use malloc. Just move the array definitions to be after you have inputted m and n:
int first[m][n];
printf("Enter Matrix A\n");
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%d", &first[i][j]);
and similarly for second and sum.
If the matrices might be larger than 100x100 then it might be good to use malloc to avoid the risk of a stack overflow; the way to do that is:
int (*first)[n] = malloc(m * sizeof *first);
printf("Enter Matrix A\n");
// etc.
and at the end, free(first);. No other changes are required.
In your attempt to use malloc, you didn't allocate enough space, and you didn't scanf into the space you allocated either (instead you overwrote the pointer to the allocated space).

Related

Check if the first and last row of a matrix has only negative values

i have some problem making this program
I have created two arrays where I go to insert the first and the last line, then I check if every element is > 0 but it doesn't seem to work..
That's my code:
int main()
{
int i, j, n, m;
int matrix[10][20];
int first_row[m];
int last_row[m];
printf("Enter number of rows : ");
scanf("%d", &n);
printf("Enter number of columns : ");
scanf("%d", &m);
/* Input data in matrix */
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
printf("Enter data in [%d][%d]: ", i, j);
scanf("%d", &matrix[i][j]);
if(matrix[i=0][j]) // First row
first_row[i] = matrix[i=0][j];
if(matrix[i=n-1][j]) // second row
last_row[i] = matrix[i=n-1][j];
}
}
for(i=0;i<n;i++)
{
for (j=j+1;j<n;j++)
{
if(last_row[i] < 0)
printf("Negative element");
}
}
}
I assume in the if conditions matrix[i=0][j] and matrix[i=n-1][j] was to check if the current row being input is the first or last row respectively. If that was the case then you just need to simply check if i is 0 (i == 0) or n - 1 (i == n-1) instead of using matrix[i=0][j] and matrix[i=n-1][j].
Also the line first_row[i] = matrix[i=0][j]; and last_row[i] = matrix[i=n-1][j]; will update i which is what you should avoid in a for loop where i is index. If you intended to assign values to first_row and last_row, you should change them to first_row[j] = matrix[0][j]; and last_row[j] = matrix[n-1][j]; to a get the desire result (note that j should be used for indexing first_row and last_row instead of i because j represents matrix column).
If you want to check every element in the matrix for negative values, then the for loop for (j=j+1;j<n;j++) should be changed to for (j=0;j<m;j++) and matrix[i][j] should be used instead of last_row[i].
Edit: Also as #chux suggested, you should consider initializing matrix, first_row and last_row arrays after you input n and m in order to avoid segmentation fault for any n and m values that are larger than 10 and 20 respectively.
#include <stdio.h>
int main()
{
int i, j, n, m;
printf("Enter number of rows : ");
scanf("%d", &n);
printf("Enter number of columns : ");
scanf("%d", &m);
int matrix[n][m];
int first_row[m];
int last_row[m];
/* Input data in matrix */
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
printf("Enter data in [%d][%d]: ", i, j);
scanf("%d", &matrix[i][j]);
if(i == 0) // First row
first_row[j] = matrix[0][j];
if(i == n-1) // second row
last_row[j] = matrix[n-1][j];
}
}
for(i=0;i<n;i++)
{
for (j=0;j<m;j++)
{
if(matrix[i][j] < 0)
printf("Negative element %d\n", matrix[i][j]);
}
}
}

Trying to multiply two large matrixes of dimension 1000*1000 causes Segmentation Fault [duplicate]

This question already has answers here:
Getting a stack overflow exception when declaring a large array
(8 answers)
Closed 4 years ago.
Trying to multiply two matrices of the dimension 1000*1000 . However, trying to do so causes Segmentation fault. what is possibly causing this and how to resolve it?
#include <stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
clock_t t;
t = clock();
long int a[1000][1000], b[1000][1000], result[1000][1000], r1=1000, c1=1000, r2=1000, c2=1000, i, j, k;
// Column of first matrix should be equal to column of second matrix and
/* while (c1 != r2)
{
printf("Error! column of first matrix not equal to row of second.\n\n");
printf("Enter rows and column for first matrix: ");
scanf("%d %d", &r1, &c1);
printf("Enter rows and column for second matrix: ");
scanf("%d %d",&r2, &c2);
}
*/
// Storing elements of first matrix.
printf("\nEnter elements of matrix 1:\n");
for(i=0; i<r1; ++i)
for(j=0; j<c1; ++j)
{
a[i][j]=rand()%20;
}
// Storing elements of second matrix.
printf("\nEnter elements of matrix 2:\n");
for(i=0; i<r2; ++i)
for(j=0; j<c2; ++j)
{
b[i][j]=rand()%20;
}
// Initializing all elements of result matrix to 0
for(i=0; i<r1; ++i)
for(j=0; j<c2; ++j)
{
result[i][j] = 0;
}
// Multiplying matrices a and b and
// storing result in result matrix
for(i=0; i<r1; ++i)
for(j=0; j<c2; ++j)
for(k=0; k<c1; ++k)
{
result[i][j]+=a[i][k]*b[k][j];
}
// Displaying the result
printf("\nOutput Matrix:\n");
for(i=0; i<r1; ++i)
for(j=0; j<c2; ++j)
{
printf("%ld ", result[i][j]);
if(j == c2-1)
printf("\n\n");
}
t = clock() - t;
double time_taken = ((double)t)/CLOCKS_PER_SEC; // in seconds
printf("\n \nfunction took %f seconds to execute \n", time_taken);
return 0;
}
You need to use dynamic memory allocation in the case of there large memory allocations. Stack memory cannot handle these large memory requirements.
You can solve this using Dynamic memory allocation. Try :-
int (*a)[r1][c1] = malloc(sizeof *a);
int (*b)[r2][c2] = malloc(sizeof *b);
int (*result)[r1][c2] = malloc(sizeof *result);
And access elements using :-
(*result)[i][j] ;
(*a)[i][k] ;
(*b)[k][j] ;
Try this code :-
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
clock_t t;
t = clock();
int r1 = 1000, c1 = 1000, r2 = 1000, c2 = 1000, i, j, k;
// Dynamic allocation.
int(*a)[r1][c1] = malloc(sizeof *a);
int(*b)[r2][c2] = malloc(sizeof *b);
int(*result)[r1][c2] = malloc(sizeof *result);
// Storing elements of first matrix.
printf("\nEnter elements of matrix 1:\n");
for (i = 0; i < r1; ++i)
{
for (j = 0; j < c1; ++j)
{
(*a)[i][j] = rand() % 20;
}
}
// Storing elements of second matrix.
printf("\nEnter elements of matrix 2:\n");
for (i = 0; i < r2; ++i)
{
for (j = 0; j < c2; ++j)
{
(*b)[i][j] = rand() % 20;
}
}
// Initializing all elements of result matrix to 0
for (i = 0; i < r1; ++i)
{
for (j = 0; j < c2; ++j)
{
(*result)[i][j] = 0;
}
}
// Multiplying matrices a and b and
// storing result in result matrix
for (i = 0; i < r1; ++i)
for (j = 0; j < c2; ++j)
for (k = 0; k < c1; ++k)
{
(*result)[i][j] += (*a)[i][k] * (*b)[k][j];
}
// Displaying the result
printf("\nOutput Matrix:\n");
for (i = 0; i < r1; ++i)
for (j = 0; j < c2; ++j)
{
printf("%d ", (*result)[i][j]);
if (j == c2 - 1)
printf("\n\n");
}
t = clock() - t;
double time_taken = ((double)t) / CLOCKS_PER_SEC; // in seconds
printf("\n \nfunction took %f seconds to execute \n", time_taken);
free(a);
free(b);
free(result);
return 0;
}
Output :-
.......................................................................
91717 92211 96529 90328 89167 88774 90433 88320 93834 89054 92225 92226 89919 88005 90772 90436 89091 92446 88477 94143 95777 88805 88487 89082 92528 88899 93436 90423 88637 90254 91569 87516 89079 91309 93554 86422 90069 91096 86981 95437 92805 88638 89828 88568 89607 88025 91700 88144 90401 91147 88284 92998 90959 85520 92640 92247 95616 90006 87248 89726 91751 90077 90543 91489 92399 90828 89026 92866 91548 87131 88450 93247 87748 90734 90228 91972 93300 92444 91592 85842 91167 89554 91144 90536 91256 89646 92815 91476 91863 94836 95462 87122 91735 96059 91312 90480 93306
function took 6.060788 seconds to execute
Note : Full output can't be included since too large.
Don't forget to free allocated memory.
First of all do not allocate such a huge amounts of memory as the local function variables. Their storage location (usually the stack) is relatively small comparing to the size of the heap You just run out of the automatic variables storage.. Instead allocate it dynamically
int *a = malloc(r1 * c1 * sizeof(*a));
int *b = malloc(r2 * c2 * sizeof(*b));
int *result = malloc(r2 * c2 * sizeof(*result));
printf("\nEnter elements of matrix 1:\n");
for(i=0; i<r1; ++i)
for(j=0; j<c1; ++j)
{
a[i * c1 + j]=rand()%20;
}
....
You can have another allocation strategy to have more natural indexing.

matrix product c, core dump error [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I've tried to create two matrices and do the product in another matrix, but the compiler gives an error of core dump. The creation of the first two matrices is right; something is wrong with the third matrix.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int m;
int n;
int t;
int i;
int **A;
int **B;
int k;
int j;
scanf("%d",&n);
scanf("%d",&m);
scanf("%d",&t);
A=malloc(n*sizeof(int*));
for(i=0;i<n;i++){
A[i]=malloc(m*sizeof(int));
}
for(i=0;i<n;i++){ // A[n][m]
for(j=0;j<m;j++)
{
scanf("%d",&(A[i][j]));
}
}
B=malloc(t*sizeof(int*));
for(i=0;i<t;i++) //B[m][t]
{
B[i]=malloc(n*sizeof(int));
}
for(i=0;i<t;i++){
for(j=0;j<n;j++)
{
scanf("%d",&(B[i][j]));
}
}
int **C;
C=malloc(t*sizeof(int*));
for(i=0;i<t;i++){{A[i]=malloc(m*sizeof(int));}
for(i=0;i<t;i++){
for(j=0;j<m;j++){
C[i][j]=0;
for(k=0;k<n;k++)
{
(C[i][j])=(C[i][j])+((A[k][j])*(B[i][k]));
}
}
}
}
return 0;
}
You must separate memory for C, not for A. That is why when you try to access C[i][j] it generates this error. Change:
for(i=0;i<t;i++){{A[i]=malloc(m*sizeof(int));}
to
for(i=0;i<t;i++){ C[i]=malloc(m*sizeof(int));}
Complete code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int m;
int n;
int t;
int i;
int **A;
int **B;
int k;
int j;
scanf("%d",&n);
scanf("%d",&m);
scanf("%d",&t);
A=malloc(n*sizeof(int*));
for(i=0;i<n;i++){
A[i]=malloc(m*sizeof(int));
}
for(i=0;i<n;i++){ // A[n][m]
for(j=0;j<m;j++){
scanf("%d", &(A[i][j]));
}
}
B=malloc(t*sizeof(int*));
for(i=0;i<t;i++) //B[m][t]
{
B[i]=malloc(n*sizeof(int));
}
printf("B\n");
for(i=0;i<t;i++){
for(j=0;j<n;j++)
{
scanf("%d",&(B[i][j]));
}
}
int **C;
C=malloc(t*sizeof(int*));
for(i=0;i<t;i++){
C[i]=malloc(m*sizeof(int));
}
for(i=0;i<t;i++){
for(j=0;j<m;j++){
C[i][j]=0;
for(k=0;k<n;k++)
{
(C[i][j])=(C[i][j])+((A[k][j])*(B[i][k]));
}
}
}
return 0;
}
Previous answers may have fixed the problem that caused the crash, but the code is still broken. It would be nice if the variables had more descriptive names. Since each variable is declared on a separate line, you could make use of the space to provide descriptive comments about the variables.
It is conventional to reference the rows of a matrix first, and then the columns. So, I will diverge from your usage, and say that matrix A has m rows and n columns. B must then have n rows, and it looks like you intend for t to hold the number of columns in B. Then the product C will be a m X t matrix.
Your code started to go wrong when you allocated space for B. You allocated for t rows of n elements, when you should have allocated for m rows of t elements (by your own notation). In my code below, because I have changed the order of m and n, I allocate for n rows of t elements.
Then, for the product matrix, I have allocated for m rows of t elements, where you had allocated for t rows of m elements. The calculation of the elements of the product matrix was also wrong in your code. The [i][j] element of C is the vector dot-product of the ith row of A and the jth column of B. The way you have calculated this element, C[i][j] is the dot-product of the jth column of A and the ith row of B.
Here is the code with corrections. I included some input prompts, and some code to display the entered matrices and the resulting product.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int m; // rows in A
int n; // cols in A
int t; // cols in B
int i;
int **A; // points to first row of A
int **B; // points to first row of B
int **C; // points to first row of C
int k;
int j;
printf("Enter number of rows in A: ");
scanf("%d", &m);
printf("Enter number of columns in A: ");
scanf("%d", &n);
printf("Enter number columns in B: ");
scanf("%d", &t);
A = malloc(sizeof(int*) * m); // A[m][n]
for(i = 0;i < m; i++){
A[i] = malloc(sizeof(int) * n);
}
for(i = 0; i < m; i++){
for(j = 0; j < n; j++)
{
scanf("%d", &(A[i][j]));
}
}
B = malloc(sizeof(int*) * n); // B[n][t]
for(i = 0; i < n; i++)
{
B[i] = malloc(sizeof(int) * t);
}
for(i = 0; i < n; i++){
for(j = 0; j < t; j++)
{
scanf("%d", &(B[i][j]));
}
}
C = malloc(sizeof(int*) * m); // C[m][t]
for(i = 0; i < m; i++){
C[i] = malloc(sizeof(int) * t);
}
for(i = 0; i < m; i++){
for(j = 0; j < t; j++){
C[i][j] = 0;
for(k = 0; k < n; k++)
{
C[i][j] = C[i][j] + A[i][k] * B[k][j];
}
}
}
printf("Matrix A:\n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("%-5d", A[i][j]);
}
putchar('\n');
}
printf("Matrix B:\n");
for (i = 0; i < n; i++) {
for (j = 0; j < t; j++) {
printf("%-5d", B[i][j]);
}
putchar('\n');
}
printf("Matrix product:\n");
for (i = 0; i < t; i++) {
for (j = 0; j < m; j++) {
printf("%-5d", C[i][j]);
}
putchar('\n');
}
return 0;
}
Here is the result of a test run:
λ> ./a.out
Enter number of rows in A: 2
Enter number of columns in A: 3
Enter number columns in B: 2
2 3 4
1 3 5
3 4
5 6
7 8
Matrix A:
2 3 4
1 3 5
Matrix B:
3 4
5 6
7 8
Matrix product:
49 58
53 62

Ways to create dynamic matrix in C?

This is the only way I know to create a matrix (2D array) in C, dynamically, and reading user input into its elements:
Creating a pointer to an array of x pointers, where each pointer
represents a line in the matrix - x is the number of lines in the matrix (its height).
Pointing each pointer in this array to an array with y elements,
where y is the number of columns in the matrix (the width).
int main()
{
int i, j, lines, columns, **intMatrix;
printf("Type the matrix lines:\t");
scanf("%d", &lines);
printf("Type the matrix columns:\t");
scanf("%d", &columns);
intMatrix = (int **)malloc(lines * sizeof(int *));
//pointer to an array of [lines] pointers
for (i = 0; i < lines; ++i)
intMatrix[i] = (int *)malloc(columns * sizeof(int));
//pointer to a single array with [columns] integers
for (i = 0; i < lines; ++i)
{
for (j = 0; j < columns; ++j)
{
printf("Type a number for <line: %d, column: %d>\t", i+1, j+1);
scanf("%d", &intMatrix[i][j]);
}
}
Are there other ways to do this?
You can try like this
int main()
{
int i, j, lines, columns, *intMatrix;
printf("Type the matrix lines:\t");
scanf("%d", &lines);
printf("Type the matrix columns:\t");
scanf("%d", &columns);
intMatrix = (int *)malloc(lines * columns * sizeof(int));
for (i = 0; i < lines; ++i)
{
for (j = 0; j < columns; ++j)
{
printf("Type a number for <line: %d, column: %d>\t", i+1, j+1);
scanf("%d", &intMatrix[i*lines + j]);
}
}
From C99 onwards (but not C++), you can use variable length arrays:
int main()
{
int i, j, lines, columns;
printf("Type the matrix lines:\t");
scanf("%d", &lines);
printf("Type the matrix columns:\t");
scanf("%d", &columns);
{
int intMatrix[lines][columns];
for (i = 0; i < lines; ++i)
{
for (j = 0; j < columns; ++j)
{
printf("Type a number for <line: %d, column: %d>\t", i+1, j+1);
scanf("%d", &intMatrix[i][j]);
}
}
}
}
Or even like this:
void readData (int lines, int columns, int array[lines][columns])
{
int i, j;
for (i = 0; i < lines; ++i)
{
for (j = 0; j < columns; ++j)
{
printf("Type a number for <line: %d, column: %d>\t", i+1, j+1);
scanf("%d", &array[i][j]);
}
}
}
int main()
{
int lines, columns;
printf("Type the matrix lines:\t");
scanf("%d", &lines);
printf("Type the matrix columns:\t");
scanf("%d", &columns);
{
int intMatrix[lines][columns];
readData (lines, columns, intMatrix);
}
}
But, in both cases, the array data is all stored on the stack, not the heap, so there's no way to store it properly, and you can't put it in a struct or anything malloc'd.
struct matrix {
type *mem;
};
struct matrix* matrix_new () {
struct matrix *M = malloc (sizeof(matrix));
M->mem = malloc (sizeof (type) * rows * cols);
return M;
}
use realloc,memcpy,memmove and free to modify chunks of the array. To access single elemnts use something like mem[row*cols+col] or mem[rows*col+row] depend on what has priority for you (or what you define a row and a column).

C how to insert a value in to a two dimenssion array

I have the following code which is driving me nuts. I am trying to input values into a 2-dimensional array.
I do not really know how I can insert a value in to specific location in the array. For example I want to enter the values in a pyramid fashion. I should be able to add one more value in each level.
a[0][0] ===> 1
a[1][0] & [1][1] &[1][2] ===> 2 3
a[2][0] & [2][0] & [2][2] ===> 4 5 6 etc.
I also want to be able to store the greatest integer In each level so that I can sum all the large integers in each level.
So far with the following code, I am unable to figure out how to insert the value and I also cannot sum the greatest values in each level.
for(i = 0; i < 2; i++){
for(j = 0; j <= 4; j++){
printf("Enter the values in to the array");
scanf("%d",&arr[i][j]);
}
}
for(i = 0; i < 2; i++){
for(j = 0; j <= 4; j++){
if(arr[i][j] > arr[i][j+1]){
holder = arr[i][j];
}else{
holder = arr[i][j+1];
}
}
sum = sum+holder;
}
printf("%d\n\n",sum);
To enter the values in a pyramid fashion & calculate the sum of the largest numbers of each row, try the code below:
int arr[5][10];
int i,j;
int holder=0;
int sum = 0;
for (i=0;i<5;i++)
{
for(j=0; j<=i;j++)
{
printf("Enter your input: \n");
scanf("%d", &arr[i][j]);
if(arr[i][j] > holder)
{
holder = arr[i][j];
}
}
printf("Largest Value in Row %d is %d\n", i, holder);
sum = sum + holder;
holder = 0;
}
printf(" Sum = %d\n", sum);
Try the code below for dynamically deciding the array size and assigning the values:-
int **arr;
int *greatest_each_lavel;
int n, i, j, temp;
printf ("enter the level.\n");
scanf ("%d", &n);
if (n<1)
{
printf ("Wrong input.\n");
exit (1);
}
greatest_each_level = (int *) malloc (n * sizeof (int));
arr = (int **) malloc (n * sizeof (int *));
for (i=1; i<=n; i++)
{
arr[i] = (int *) malloc (i * sizeof (int));
}
// Populate the array members.
for (i=0; i<n; i++)
{
temp = 0;
for (j=0; j<=i; j++)
{
printf ("Enter the number ");
scanf ("%d", &arr[i][j]);
if (arr[i][j] > k)
{
temp = arr[i][j];
}
}
greatest_each_level[i] = temp;
}
// To get the sum of greatest number at each level
int sum = 0;
for (i = 0; i < n; i++)
sum = sum + greatest_each_level[i];
printf ("Sum is : %d\n", sum);
// When all task are done, dont forget to free the memory.
for (i=0; i<n; i++)
{
free (arr[i]);
}
free (arr);
free (greatest_each_level);
greatest_each_level = NULL;
arr = NULL;

Resources