how to build function that multiply matrices created via struct in C - c

I am supposed to build a matrix_mul function that display the result of a multiplication between two matrices that were created via a struct. My problem is, my function does not multiply the value inside the matrices instead it return an interger.
#include<stdio.h>
#include<stdlib.h>
typedef struct{
int rows;
int cols;
int **data;
} matrix;
matrix matrix_mul(int **a, int **b){
int rowA=(sizeof(a)/sizeof(a[0]));
int colA=(sizeof(a)/sizeof(a[0][0]))/rowA;
int rowB=(sizeof(b)/sizeof(b[0]));
int colB=(sizeof(b)/sizeof(b[0][0]))/rowB;
int i, j, **mulMatrix;
if(colA != rowB)
printf("error: cannot multiply matrices");
else{
int i, j, k;
mulMatrix = (int **)malloc(rowA * sizeof(int *));
for(i=0; i<rowA; i++)
mulMatrix[i] = (int *)malloc(colB * sizeof(int));
for(i=0; i<rowA; ++i){
for(j=0; j<colB; ++j){
for(k=0; k<colA; ++k)
{
mulMatrix[i][j]+= a[i][k] * b[k][j];
}
}
}
}
printf("Matrix: \n\n");
for(i=0; i< rowA; i++){
for(j=0; j< colB; j++){
printf("%d ", mulMatrix[i][j]);
}
printf("\n\n");
}
}
int main()
{
int i, j;
matrix a, b;
printf("matrix1 - enter number of rows and cols: ");
scanf("%d %d", &a.rows, &a.cols);
a.data = (int **)malloc(a.rows * sizeof(int *));
printf("enter matrix values: ");
for(i=0; i<a.rows; i++){
a.data[i] = (int *)malloc(a.cols * sizeof(int));
for(j=0; j<a.cols; j++){
scanf("%d", &a.data[i][j]);
}
}
printf("matrix2 - enter number of rows and cols: ");
scanf("%d %d", &b.rows, &b.cols);
b.data = (int **)malloc(b.rows * sizeof(int *));
printf("enter matrix values: ");
for(i=0; i<b.rows; i++){
b.data[i] = (int *)malloc(b.cols * sizeof(int));
for(j=0; j<b.cols; j++){
scanf("%d", &b.data[i][j]);
}
}
matrix_mul(a.data, b.data);
return 0;
}

These lines
int rowA=(sizeof(a)/sizeof(a[0]));
int colA=(sizeof(a)/sizeof(a[0][0]))/rowA;
won't give you the results you are looking for.
sizeof(a) is sizeof(int**) and sizeof(a[0]) is sizeof(int*). Since pointers are usually of the same size, rowA will be always set to 1. colA will be set to sizeof(int**)/sizeof(int), which is a constant value. Once again, it's not the value you are hoping to get.
You should pass the matrix objects, a and b to matrix_mul. That'll give you the size of the matrices to use for multiplying them.
matrix matrix_mul(matrix a, matrix b){
Of course, you need to modify the implementation accordingly.

Related

Function inputElements() taking input only once

I am trying to create a program to find the transpose of a matrix my dynamic memory allocation. However, while entering the elements of the matrix I can't input more than one element, its only taking the a[0][0] as the input and the program is ending after that.
#include <stdio.h>
#include <stdlib.h>
void createMatrix(int **, int, int);
void inputElements(int **, int, int);
void transpose(int **, int **, int, int);
void display(int **, int, int);
void main()
{
int **matrix, **trans, rows, cols;
printf("\nEnter number of rows in the matrix: ");
scanf("%d", &rows);
printf("\nEnter number of columns in the matrix: ");
scanf("%d", &cols);
createMatrix(matrix, rows, cols);
createMatrix(trans, cols, rows);
inputElements(matrix, rows, cols);
transpose(matrix, trans, rows, cols);
printf("\nMATRIX:\n");
display(matrix, rows, cols);
printf("\nTRANSPOSE OF THE MATRIX:\n");
display(trans, rows, cols);
}
void createMatrix(int **a, int r, int c) //for allocating memory for the matrix
{
int i, j;
a = (int **)malloc(sizeof(int *) * r);
for(i = 0; i < r; i++)
a[i] = (int *)malloc(sizeof(int) * c);
}
void inputElements(int **a, int r, int c) //for entering matrix elements
{
int i, j, t;
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
printf("\nEnter matrix element[%d][%d]: ", i + 1, j + 1);
fflush(stdin);
getchar();
scanf("%d", &(a[i][j]));
}
}
}
void transpose(int **a, int **t, int r, int c) //for finding out the transpose of the matrix
{
int i, j;
for (i = 0; i < c; i++)
{
for (j = 0; j < r; j++)
t[i][j] = a[j][i];
}
}
void display(int **a, int r, int c) //for displaying the matrix
{
int i, j;
for (i = 0; i < r; i++)
{
printf("\n");
for (j = 0; j < c; j++)
printf("\t%d", a[i][j]);
}
}
There are many posts about scanf in loops I've seen, but I wasn't able to connect my issue with any of them.

Returning pointer to allocated memory?

My task is to write a function int *matrica1(int n). This function must create a matrix dimensions nxn and then you have to allocate its memory and in the main you have to write the elements of the matrix. I have a problem when returning pointer mat1 to **p and when i call **p i get a address instead of a number but when i call **mat1 in the function i get the number. I do not understand ?
#include <stdio.h>
int *matrica1(int n);
int main(){
int n;
printf("Input dimension of matrix:");
scanf("%d", &n);
int **p = matrica1(n);
printf("Matrix \n\n");
int i;
n = n*n;
for(i=0; i<n; i++){
printf(" %d ", **(p+i));//I keep getting an address
}
return 0;
}
int *matrica1(int n){
int mat[n][n];
int i, j;
int k=0;
for(i=0; i<n; i++){
for(j=0; j<n; j++){
mat[i][j] = j+k;
}
k++;
}
int size = n*n;
int **mat1 = (int*)malloc(size*sizeof(int));
int m = 0;
for(i=0; i<n; i++){
for(j=0; j<n; j++){
mat1[m] = &mat[i][j];
m++;
}
}
printf("\n\n**mat1 = %d", **mat1);//Here it returns me a number
return mat1;
}
here how it looks like when running it
You're returning the address of a local variable.
mat1 contains pointers to element of mat. When matrica1 returns, mat goes out of scope, so pointers to its elements no longer point to valid memory. Dereferencing these pointers invokes undefined behavior.
Other problems:
The memory you're assigning to mat1 is not the right size. Because it is an array of int *, you should be allocating size*sizeof(int *) bytes, not size*sizeof(int) bytes.
matrica1 is defined to return a int * but you're returning an int ** and assigning the result to an int **. The return type of the function must match what you're returning.
Rather than having mat1 be an array of int *, make it an array of int and copy the values of mat rather than the addresses:
#include <stdio.h>
int *matrica1(int n);
int main(){
int n;
printf("Unesite dimenziju matrice:");
scanf("%d", &n);
// Have p match return type of function
int *p = matrica1(n);
printf("Matrix \n\n");
int i;
n = n*n;
for(i=0; i<n; i++){
// print array elements
printf(" %d ", *(p+i));
}
return 0;
}
int *matrica1(int n){
int mat[n][n];
int i, j;
int k=0;
for(i=0; i<n; i++){
for(j=0; j<n; j++){
mat[i][j] = j+k;
}
k++;
}
int size = n*n;
// change type of mat1 from int ** to int *, keep size the same
int *mat1 = malloc(size*sizeof(int));
int m = 0;
for(i=0; i<n; i++){
for(j=0; j<n; j++){
// assign values of mat instead of addresses
mat1[m] = mat[i][j];
m++;
}
}
printf("\n\n*mat1 = %d", *mat1);
return mat1;
}
Output:
Unesite dimenziju matrice:5
*mat1 = 0Matrix
0 1 2 3 4 1 2 3 4 5 2 3 4 5 6 3 4 5 6 7 4 5 6 7 8

Refilling 2D arrays in c

I have two 2d arrays "a", "b" (empty array) with the same size, I have to change "a" due to a certain function that save it's new values in "b", then I have to change the new values according to the same function, so the program will save b's new values in a and then back to a.
When the arrays are printed only the first two ones are printed!!
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MSIZE 10
void new_gen(char * a[MSIZE],int s,char** b); /*the function we talked about*/
void print_m(char** b,int s); /*prints matrix*/
void cpy_m(char** b, char** a, int s);
int main()
{
int Size, gen, i, j;
printf("Enter number of generations\t");
scanf("%d", &gen);
printf("\nEnter size of the matrix (max size is %d and min is 2)\t", MSIZE);
scanf("%d", &Size);
char **m = (char**) malloc(Size*sizeof(char*));
for (i=0; i<Size; i++)
{
m[i] = (char*) malloc(Size*sizeof(char));
}
printf("Enter matrix of first generation\n");
for (i=0; i<Size; i++) {
for (j=0; j<Size; j++) {
scanf(" %c", &m[i][j]);
}
}
print_m(m, Size);
for (i=1; i<gen; i++)
{
char **n = (char**) malloc(Size*sizeof(char*));
for (i=0; i<Size; i++)
{
n[i] = (char*) malloc(Size*sizeof(char));
}
new_gen(m, Size, n);
print_m(n, Size);
cpy_m(n, m, Size);
}
return 0; }
void print_m(char** b, int s)
{
int i, j;
putchar('\n');
for (i=0; i<s; i++)
{
for (j=0; j<s; j++) {
printf("%c", *(*(b+i)+j));
}
putchar('\n');
}
return;
}
void cpy_m(char* b[MSIZE],char** a, int s)
{
int i, j;
for (i=0; i<s; i++) {
for (j=0; j<s; j++) {
*(*(a+i)+j) = b[i][j];
}
return;
}}
Consider this pair of nested loops
for (i=1; i<gen; i++)
{
char **n = (char**) malloc(Size*sizeof(char*));
for (i=0; i<Size; i++)
{
n[i] = (char*) malloc(Size*sizeof(char));
}
new_gen(m, Size, n);
print_m(n, Size);
cpy_m(n, m, Size);
}
First point, both the loops use i as the control variable, but they are nested.
Second point, you overwrite the pointers from malloc in each iteration (there is no free).

2D array, sort rows by sum

There is 2D array with pointers from user, filled with random numbers, program count sum of every row. I need to sort array by sum of every row and print it. For example if we have array:1 2 2 (sum=5)2 9 9 (sum=20)2 1 6 (sum=9)
output should be:1 2 2 (sum=5)2 1 6 (sum=9)2 9 9 (sum=20). Thanks for help.
int main () {
int i, j, row, column, **array,sum;
time_t seconds;
time (&seconds);
srand ((unsigned int)seconds );
printf ("Write number of rows:");
scanf ("%d", &row);
printf ("Write number of columns:");
scanf ("%d", &column);
array=(int**) malloc (row * sizeof(int *));
if (array!=NULL){
for (i=0; i<row;i++)
array[i]= (int*) malloc (column *sizeof(int));
}
for (i=0; i<row;i++)
for (j=0; j<column;j++)
array[i][j]=(rand()%100);
for (i=0; i<row;i++){
for (j=0; j<column;j++)
printf("%d ",array[i][j] );
printf ("\n");
}
for(i=0;i<row;i++){ //find sum of each row
sum=0;
for(j=0;j<column;j++){
sum=sum+array[i][j];
}
printf("%d \n",sum);
}
return 0;
}
sample of option 1
#include <stdio.h>
#include <stdlib.h>
int COLUMNS;
int sum(int len, int *array){
int i, sum = 0;
for(i=0; i<len; ++i)
sum += *array++;
return sum;
}
int cmp(const void *a, const void *b){
int sum1 = sum(COLUMNS, *(int**)a);
int sum2 = sum(COLUMNS, *(int**)b);
return (sum1 > sum2) - (sum1 < sum2);
}
int main(void){
int i, j, row, column, **array;
row = 3; column = 3;
array = (int**) malloc (row * sizeof(*array));//cast of (int**) is redundant.
array[0] = (int []){1, 2, 2};
array[1] = (int []){2, 9, 9};
array[2] = (int []){2, 1, 6};
COLUMNS = column;//size of columns pass to compare function by global variable.
qsort(array, row, sizeof(*array), cmp);
for (i=0; i<row;i++){
for (j=0; j<column;j++)
printf("%d ",array[i][j] );
printf ("\n");
}
free(array);
return 0;
}
sample of option 2
#include <stdio.h>
#include <stdlib.h>
int sum(int len, int *array){
int i, sum = 0;
for(i=0; i<len; ++i)
sum += *array++;
return sum;
}
typedef struct pair {
int *p;//or index
int sum;
} Pair;
int cmp(const void *a, const void *b){
Pair const *x = a;
Pair const *y = b;
return (x->sum > y->sum) - (x->sum < y->sum);
}
int main(void){
int i, j, row, column, **array;
row = 3; column = 3;
array = (int**) malloc (row * sizeof(*array));//cast of (int**) is redundant.
array[0] = (int []){1, 2, 2};
array[1] = (int []){2, 9, 9};
array[2] = (int []){2, 1, 6};
Pair *temp = malloc(row * sizeof(*temp));
for(i = 0; i < row; ++i){
temp[i].p = array[i];
temp[i].sum = sum(column, array[i]);
}
qsort(temp, row, sizeof(*temp), cmp);
for (i=0; i<row;i++){
for (j=0; j<column;j++)
printf("%d ", temp[i].p[j] );
printf ("\n");
}
free(temp);
free(array);
return 0;
}

how to store multiple arrays and make array of pointers to them

I don't have a lot of experience with pointers, but I want to try to make an array of pointers, each pointer pointing to a scanned string.
For example, you first input how many strings you want to scan (for example 5), and then I want to scan those strings and make an array of 5 pointers that point to those strings.
Because I didn't have a lot experience with something like this, I first tried it with normal arrays instead of strings, what I got is this:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
int **array(int m, int n) {
int i, j;
int **array = malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, *p, k;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=*array(m, n);
printf("the numbers are:\n");
for (k=0; k<m*n; k++) {
printf("%d\n", p[k]);
}
return 0;
}
But here it's already going wrong, and I don't know why...
At the last printf, I always get wrong numbers, 0's and 17's...
Can someone explain me why this is and what I'm doing wrong? I think it's something with the returning of the array but I'm not sure..
If someone could explain this to me it would be great.
The problem with your code is the following:
// m = 3, n = 5
// array = ptr1, ptr2, ptr3, ptr4, ptr5
// | |
// 3 ints |
// 3 ints ..
int **array(int m, int n) {
int i, j;
int **array = (int**)malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=(int*)malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
In the above example (m=3, n=5) you allocated 5 pointers to integers and then tried to populate them by allocating memory at each iteration in the inner-loop (WRONG). If you allocate new memory at each iteration, you're gonna lose the pointer to the previously allocated memory and the data you stored!
Plus the indices seem to be wrong for the inner and outer loop, a correct version of your code is:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
// 3, 5
// array = ptr1, ptr2, ptr3, ptr4, ptr5
// | |
// 3 ints |
// 3 ints ..
int **array(int m, int n) {
int i, j, index;
int **array = (int**)malloc(n*sizeof(int*));
index = 0;
for (j=0; j<n; j++) {
array[j]=(int*)malloc(m * sizeof(int)); // Allocate once per each j
for (i=0; i<m; i++) {
array[j][i] = index++;
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, **p, k, i, j;
m = 3;
n = 5;
printf("m is %d and n is %d\n", m, n);
p=array(m, n);
printf("the numbers are:\n");
for (j=0; j<n; j++)
for(i=0; i<m; i++)
printf("%d\n", p[j][i]);
return 0;
}
And the above version is STILL NOT CORRECT : You need to free the allocated memory!
I'll leave that as an exercise.. hint: you CAN'T simply do "free(p);" :]
Are you sure about this for loop? If you've the malloc inside the inner loop you're not creating a matrix because every time you override the same cells...
int i, j;
int **array = malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
It should be something like:
int i, j;
int **array = malloc(n*sizeof(int*));
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
for (j=0; j<m; j++) {
scanf("%d", &array[i][j]);
printf("array[%d][%d] is scanned and has value %d\n", i, j, array[i][j]);
}
}
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
void *array(int m, int n) {
int i, j;
int (*array)[n] = malloc(sizeof(int [m][n]));//m*n*sizeof(int)
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, *p, k;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=(int*)array(m, n);
printf("the numbers are:\n");
for (k=0; k<m*n; k++) {
printf("%d\n", p[k]);
}
return 0;
}
#include <stdlib.h>
#include <stdio.h>
char **array(int m, int n) {
int i;
char **array = malloc(m*sizeof(char*));
for (i=0; i<m; ++i) {
array[i] = malloc(n*sizeof(char));//Fixed length : like char array[m][n] (char *array[m])
scanf("%s", array[i]);//!! There is no length constraints.
printf("array[%d] is scanned and has value %s\n", i, array[i]);
}
return array;
}
int main(int argc, char*argv[]){
int m, n, k;
char **p;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=array(m, n);
printf("the string are:\n");
for (k=0; k<m; ++k) {
printf("%s\n", p[k]);
}
return 0;
}
I'm not sure if I do this smart, but I usually allocate the pointer array and then allocate the whole memory chunk to the first item. Then I get continuous memory for the data. Like:
_array = (float**) malloc( n * sizeof ( float * ));
assert ( _array != NULL );
_array[0] = (float*) malloc( n * m * sizeof ( float ));
assert ( _array[0] != NULL );
for ( idx = 0; idx < n; idx++ )
_array[ idx ] = _array[ 0 ] + idx * m;
(float instead of int in my case. And please don't comment on the return of malloc casting, nor on the silly user of assert())

Resources