Creating dynamic two dimensional array in C - c

I want to write a program that calculates a matrix multiplication.
However, it seems like there is a problem concerning the memory allocation. For m <= 2 and n <= 2, the code works just fine but after staring at it for an hour, I still can't figure out why the program blows up vor values greater than that (SegFault and free_matrix() is complaining about trying to free not allocated memory).
Here is my Code:
#include <stdio.h>
#include <stdlib.h>
typedef double *Vector;
typedef Vector *Matrix;
//Initializes a matrix of given size
Matrix mat_alloc(int m, int n){
Matrix mat = NULL;
mat = (Matrix)malloc(sizeof(m * sizeof(Vector)));
if(mat == NULL){
printf("Error: Not Enough Memory!\n");
return NULL;
}
for(int i = 0; i < m; i++){
mat[i] = (Vector)malloc(n * sizeof(double));
if(mat[i] == NULL){
printf("Error: Not Enough Memory!\n");
return NULL;
}
}
return mat;
}
Matrix mat_mult(Matrix A, Matrix B, int m, int n, int k){
Matrix C = mat_alloc(m, k);
for(int i = 0; i < m; i++){
for(int j = 0; j < k; j++){
C[i][j] = 0;
for(int l = 0; l < n; l++){
C[i][j] += A[i][l] * B[l][j];
}
}
}
return C;
}
void print_matrix(Matrix mat, int m, int n){
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
printf("%.2lf ", mat[i][j]);
}
printf("\n");
}
}
void read_matrix(Matrix mat, int m, int n){
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
printf("(%d,%d) = ", i+1, j+1);
scanf("%lf", &mat[i][j]);
}
}
}
void free_matrix(Matrix mat, int m){
for(int i = 0; i < m; i++){
free(mat[i]);
}
free(mat);
}
int main(int argc, char *argv[]){
int m = 0;
int n = 0;
int k = 0;
printf("Dimensions of A (m x n):\n");
printf("m = ");
scanf("%d", &m);
printf("n = ");
scanf("%d", &n);
printf("Dimensions of B (n = %d x k):\n", n);
printf("k = ");
scanf("%d", &k);
printf("Your input: m = %d, n = %d, k = %d\n", m, n, k);
Matrix A = NULL;
Matrix B = NULL;
Matrix C = NULL;
A = mat_alloc(m, n);
B = mat_alloc(n, k);
printf("Enter Values for A!\n");
read_matrix(A, m, n);
printf("Enter Values for B!\n");
read_matrix(B, n, k);
printf("A = \n");
print_matrix(A, m, n);
printf("\nB = \n");
print_matrix(B, n, k);
C = mat_mult(A, B, n, m, k);
printf("\nC = \n");
print_matrix(C, m, k);
free_matrix(A, m);
free_matrix(B, n);
free_matrix(C, m);
return 0;
}
Thank you in advance.

This here:
mat = (Matrix)malloc(sizeof(m * sizeof(Vector)));
Should be
mat = (Matrix)malloc(m * sizeof(Vector));
Or better yet
mat = malloc(sizeof *mat * m);
You have a sizeof too much, so instead of getting the desired size of the pointer array, you get a constant (the size of a size_t).

Related

How to raise a matrix to a power with double pointers in C

I am trying to raise a matrix to a power, using pointers but there is a mistake in my code I can't find.
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
>
int **alloc(int r, int c) {
int **d;
d = (int **)malloc(r * sizeof(int *));
for (int i = 0; i < r; i++) {
d[i] = (int *)malloc(c * sizeof(int));
}
return d;
void input(int **A, int r, int c) {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("[%d][%d]=", i, j);
scanf_s("%d", &A[i][j]);
}
}
}
void output(int **A, int r, int c) {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("%d ", A[i][j]);
}
printf("\n");
}
}
void power(int **A,int**D, int r, int c,int p) {
int i, j,k;
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++) {
D[i][j] = A[i][j];
}
}
while (p) {
// this is the matrix multiplication, where I attempt to multiply my matrix A with itself, and store the result in D, which initially started as A's copy, and p is the power I'm raising it to.
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++) {
for (k = 0; k < c; k++)
D[i][j] = D[i][j] + A[i][k] * D[k][j];
}
}
p--;
}
}
void main() {
int r, c;
int **A, **D;
printf("rows A: ");
scanf_s("%d", &r);
printf("columns A: ");
scanf_s("%d", &c);
A = alloc(r, c);
printf("\nValues of A:\n");
input(A, r, c);
printf("\nMatrIX A is:\n");
output(A, r, c);
D = alloc(r, c);
printf("input the value you want to raise your matrix to: ");
int p;
scanf_s("%d", &p);
power(A, D, r, c, p);
printf("\nMatrix raised to said power is:\n");
output(D, r, c);
_getch();
}
When I input the rows and columns as 2 each, and input all values in the matrix as 1 and raise it to the power of 3, my answer should be
4 4
4 4
instead of
72 72
232 232
What is wrong in my code? If I were to print the D matrix before the multiplication, it would print it correctly, as:
1 1
1 1
Your two-step allocation looks okay, except that you don't free the memory after you're done. Your problem is in how you multiply the matrix:
Raising a matrix to a power involves multiplying it to itself. You can only do that if the matrix is square. You can replace all occurrences of rows r and columns c with a single dimension n.
When you do the actual multiplication:
D[i][j] = D[i][j] + A[i][k] * D[k][j];
you assign to D and read from it at the same time. Subsequent calculations (of the same multiplication) will see a changed value of D[i][j]. You will need a temporary "scratch" matrix.
Your code multiplies once too many. Also, Raising a matrix to the power of zero should yield the identity matrix.
Here's how your power function could look like:
void power(int **A, int **D, int n, int p)
{
int i, j,k;
// assign identity matrix to result D
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
D[i][j] = (i == j);
}
}
// create a scratch matrix
int **tmp = alloc(n);
while (p-- > 0) {
// multiply [tmp] = [A] * [D]
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
tmp[i][j] = 0;
for (k = 0; k < n; k++)
tmp[i][j] += A[i][k] * D[k][j];
}
}
// copy [D] = [tmp]
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
D[i][j] = tmp[i][j];
}
}
}
// TODO: clean up the scratch matrix
}

I'm getting this error: Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)

I need help here! I'm trying to code a console-based C program which solves several systems of equations.
Exercise:
The program receives an entry file (input and output file names typed in by the user), containing n, m, and a bunch of numbers which will fill in a matrix. This matrix is an extended matrix which has n rows and n+m columns (where m is the number of systems to solve). First "submatrix" nxn must be reduced using Gauss Elimination method with pivoting.
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int gauss_pivot (double **a, int n, int m, double tol);
void resol (double **a, int n, int m);
int main(void) {
double **ampliada;
int n, m;
int i, j;
FILE *entrada, *sortida;
char nomE[31], nomS[31];
printf("Noms dels fitxers d'entrada i sortida\n");
scanf("%s %s", nomE, nomS);
entrada = fopen(nomE, "r");
sortida = fopen(nomS, "w");
if (entrada == NULL || sortida == NULL){
if (entrada == NULL){
printf("Error en el fitxer d'entrada\n");
exit(1);
}
else{
printf("Error en el fitxer de sortida\n");
exit(1);
}
}
fscanf(entrada, "%d", &n);
fscanf(entrada, "%d", &m);
ampliada = (double**)malloc(n*sizeof(double*));
if (ampliada == NULL) {
printf("Memòria insuficient\n");
exit(1);
}
for (i=0; i<n; i++){
ampliada[i] = (double*)malloc(m*sizeof(double));
if (ampliada[i] == NULL){
printf("Memòria insuficient\n");
exit(1);
}
}
for (i=0; i<n; i++){
for (j=0; j<=m; j++){
fscanf(entrada, "%le", &ampliada[i][j]);
}
}
gauss_pivot(ampliada, n, m, 10^(-16));
resol(ampliada, n, m);
return 0;
}
int gauss_pivot (double **a, int n, int m, double tol){
float q;
double pivot, aux;
int r;
for (int j = 0; j < n; j++){
pivot = 0;
for (r = j; r < n; r++){
if (fabs(a[r][j]) > pivot){
pivot = a[r][j];
}
}
if (pivot != a[j][j]){
for (int s = 0; s < (n+m); s++){
aux = a[r][s];
a[r][s] = a[j][s];
a[j][s] = aux;
}
}
for (int i = 0; i < n; i++){
if(i > j){
q = a[i][j]/a[j][j];
for (int k = 0; k < (n+m); k++){
a[i][k] = a[i][k] - q*a[j][k];
}
}
}
}
return 0;
}
void resol (double **a, int n, int m){
double resultats[n], suma;
for (int s = 1; s <= m; s++){
printf("Solució al sistema %d:\n", s);
resultats[n]=a[n][n+1]/a[n][n];
for(int i = n-1; i >= 1; i--){
suma=0;
for(int j=i+1; j<=n; j++){
suma=suma+a[i][j]*resultats[j];
}
resultats[i]=(a[i][n+1]-suma)/a[i][i];
}
for (int r = 1; r <= n; r++){
printf("X_%d = %f", r, resultats[r]);
}
}
}
It crashes on the following lines (sometimes one, somtimes the other):
aux = a[r][s];
a[r][s] = a[j][s];
a[j][s] = aux;
And I get the following error message:
Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
What am I doing wrong?

C: Why doesn't this code work?

Need help with this code it should return c[] with the number's of a[] % b[] = 0 but it doesn't work.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *divide(int a[], int a_size, int b[], int b_size)
{
int i = 0, j = 0, k = 0, counter = 0, *c;
c = (int*)malloc(b_size * sizeof(int));
for (i = 0; i < b_size; i++)
{
for (j = 0; j < a_size; j++)
{
if (a[j] % b[i] == 0)
counter++;
}
c[k] = counter;
k++;
counter = 0;
}
for (int t = 0; t < b_size; t++)
{
printf("%d ", c[t]);
}
printf("\n");
}
main ()
{
int *a, *b, a_size, b_size;
printf("Enter size of a:\n");
scanf ("%d", &a_size);
a = (int*)malloc(a_size * sizeof(int));
printf("\nEnter size of b:\n");
scanf("%d", &b_size);
b = (int*)malloc(b_size * sizeof(int));
printf("\nEnter elements of a:\n");
for (int i = 0; i < a_size; i++)
{
scanf("%d", &a[i]);
}
printf("\nEnter elements of b:\n");
for (int j = 0; j < b_size; j++)
{
scanf("%d", &b[j]);
}
divide(&a, a_size, &b, b_size);
}
There was some errors in your code.
You want your fonction *divide(...) to return a new array containing the operation a[i] % b[i], but your function doesn't return anything, so you have to return it. It seems more logical to print the new array in the main, than in the function while doing it.
When you pass the variables to your function be careful to pass int*, not int **.
Here is a sample of code which works (you didn't say what to do if a_size and b_size were different so I assume we only use the smallest size and don't treat the number after) :
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *divide(int a[], int a_size, int b[], int b_size)
{
int i = 0, stop, *c;
if (b_size <= a_size)
{
c = (int*)malloc(b_size * sizeof(int));
stop = b_size;
}
else
{
c = (int*)malloc(a_size * sizeof(int));
stop = a_size;
}
while (i < stop)
{
c[i] = a[i] % b[i];
i++;
}
return (c);
}
int main ()
{
int *a, *b, a_size, b_size;
int *result = NULL;
int stop;
int i = 0;
printf("Enter size of a:\n");
scanf ("%d", &a_size);
a = (int*)malloc(a_size * sizeof(int));
printf("\nEnter size of b:\n");
scanf("%d", &b_size);
b = (int*)malloc(b_size * sizeof(int));
printf("\nEnter elements of a:\n");
for (int i = 0; i < a_size; i++)
{
scanf("%d", &a[i]);
}
printf("\nEnter elements of b:\n");
for (int j = 0; j < b_size; j++)
{
scanf("%d", &b[j]);
}
result = divide(a, a_size, b, b_size); //not &a neither &b because it would be a char** instead of a char*
if (a_size < b_size)
stop = a_size;
else
stop = b_size;
while (i < stop)
{
printf("%d ", result[i]);
i++;
}
return 0;
}

variable length multidimensional arrays

I did this program for a homework and it crashes without any error when run.
Also after correcting it, any suggestions to increase the efficiency of my coding approach are appreciated.
First I declared m,n,p,q as global variables an I passed only the arrays to the functions, but the program behaved weird.
Then I included the dimensions of the arrays as arguments in every function and declared it everywhere. CRASH
*VLA SUPPORTED
//functions on matrices
#include<stdio.h>
int i, j;
void getMatrix(int m, int n, int values[m][n]);
void displayMatrix(int m, int n, int values[m][n]);
void transposeMatrix(int m, int n, int values[m][n]);
void addMatrices(int m, int n, int p, int q, int A[m][n], int B[p][q]);
void multiplyMatrices(int m, int n, int p, int q, int A[m][n], int B[p][q]);
int main()
{
int m, n, p, q, A[m][n], B[p][q];
printf("Enter the no. of Rows of the first Matrix : ");
scanf("%d", &m);
printf("Enter the no. of Columns of the first Matrix : ");
scanf("%d", &n);
printf("Enter the elements of the first matrix: \n");
getMatrix(m, n, A);
printf("The entered Matrix:\n");
displayMatrix(m, n, A);
printf("The transpose of the entered Matrix:\n");
transposeMatrix(m, n, A);
printf("Enter the no. of Rows of the second Matrix : ");
scanf("%d", &p);
printf("Enter the no. of Columns of the second Matrix : ");
scanf("%d", &q);
printf("Enter the elements of the secong matrix: \n");
getMatrix(p, q, B);
printf("The entered Matrix:\n");
displayMatrix(p, q, B);
printf("The transpose of the entered Matrix:\n");
transposeMatrix(p, q, B);
printf("Addition of the Matrices:\n");
addMatrices(m, n, p, q, A, B);
printf("Multiplication of the Matrices:\n");
multiplyMatrices(m, n, p, q, A, B);
return 0;
}
void getMatrix(int m, int n, int values[m][n])
{
for(i = 0; i < m; ++i)
for(j = 0; j < n; ++j)
scanf("%d", &values[i][j]);
}
void displayMatrix(int m, int n, int values[m][n])
{
for(i = 0; i < m; ++i)
{
for(j = 0; j < n; ++j)
printf("%3d ", values[i][j]);
printf("\n");
}
}
void transposeMatrix(int m, int n, int values[m][n])
{
int transpose[n][m];
for(i = 0; i < n; ++i)
for(j =0; j < m; ++j)
transpose[i][j] = values[j][i];
displayMatrix(n, m, transpose);
}
void addMatrices(int m, int n, int p, int q, int A[m][n], int B[p][q])
{
int C[m][n];
if(m == p && n == q)
{
for(i = 0; i < m; ++i)
for(j = 0; j < n; ++j)
C[i][j] = A[i][j] + B[i][j];
displayMatrix(m, n, C);
}
else
printf("Cannot add these Matrices!\n");
}
void multiplyMatrices(int m, int n, int p, int q, int A[m][n], int B[p][q])
{
int C[m][q], k, sum = 0;
if(n == p)
{
for(i = 0; i < m; ++i)
for(j = 0; j < q; ++j)
{
for(k = 0; k < n; ++k)
sum += A[i][j] * B[j][i];
C[i][j] = sum;
sum = 0;
}
displayMatrix(m, q, C);
}
else
printf("Cannot multiply these Matrices!\n");
}
Initiliazie m and n so that you don't get UB when using them in array index in VLA.
Unsed loop in multiply matrices
for(k = 0; k < n; ++k)
sum += A[i][j] * B[j][i];
will be
for(k = 0; k < n; ++k)
sum += A[i][k] * B[k][j];
Don't use global variables unless you need to. It is good practice to make index variables of for loop local.
for(int i=0;i<n;i++)
...

c - warning: pointer argument of a function may be used uninitialized

#include <stdio.h>
#include <stdlib.h>
void multiplyMatrix (int **first, int **second, int **multiply);
int m, n, p, q, i, c, d, k, sum = 0;
int main()
{
int **first, **second, **multiply;
printf("Enter the number of rows and columns of first matrix\n");
scanf("%d%d", &m, &n);
first = (int **) malloc(m * sizeof(int *));
for(i = 0 ; i < n ; i++){
first[i]=(int *)malloc(m * sizeof(int *));
}
printf("Enter the elements of first matrix\n");
for (c = 0; c < m; c++)
for (d = 0; d < n; d++)
scanf("%d", &first[c][d]);
printf("Enter the number of rows and columns of second matrix\n");
scanf("%d%d", &p, &q);
second = (int **) malloc(p * sizeof(int *));
for(i = 0 ; i < q ; i++){
second[i]=(int *) malloc(p * sizeof(int *));
}
if (n != p)
printf("Matrices with entered orders can't be multiplied with each other.\n");
else
{
printf("Enter the elements of second matrix\n");
for (c = 0; c < p; c++)
for (d = 0; d < q; d++)
scanf("%d", &second[c][d]);
/*for (c = 0; c < m; c++) {
for (d = 0; d < q; d++) {
for (k = 0; k < p; k++) {
sum = sum + first[c][k]*second[k][d];
}
multiply[c][d] = sum;
sum = 0;
}
}*/
multiplyMatrix(first, second, multiply);
printf("Product of entered matrices:-\n");
for (c = 0; c < m; c++) {
for (d = 0; d < q; d++)
printf("%d\t", multiply[c][d]);
printf("\n");
}
}
return 0;
}
void multiplyMatrix (int **first, int **second, int **multiply)
{
for (c = 0; c < m; c++) {
for (d = 0; d < q; d++) {
for (k = 0; k < p; k++) {
sum = sum + first[c][k]*second[k][d];
}
multiply[c][d] = sum;
sum = 0;
}
}
}
The program i want to write should be like this: The program asks to the user to enter both the sizes and elements of 2 matrices (or you can call it 2d arrays). Then it will multiply those matrices and print the answer.
The problem i am getting: i used pointers and malloc functions to dynamically allocate the matrices. for the multiplication, i created a function called "multiplyMatrix" which i get a warning for one of the arguments of it in the decleration. here is the warning:
warning: 'multiply' may be used uninitialized in this function.
so there is some kind of a problem with initializing this argument. i feel like the answer is simple but at the same time i can't find the solution.
You have not allocated the memory to be used by the multiply matrix - hence it is being flagged as uninitialised.
You also need to review how you use your row and column values when allocating the first and second matrices, for example:
first = (int **) malloc(m * sizeof(int *));
for(i = 0 ; i < m ; i++){
first[i]=(int *)malloc(n * sizeof(int *));
}
(Incorporates comment made by wildplasser)
This will allow first to be accessed as first[row][col]
the variable multiply was declared in main(), however it is never set to point to anything. it needs to be created the same way as first and second, however it does not need to have its' values filled in.
Suggestions to improve your code:
Create a function to allocate memory for a matrix.
Create a function to read matrix data.
Create a function to deallocate memory of a matrix.
Avoid use of global variables. Pass the necessary arguments to a function.
Use those functions instead of duplicating code in main.
#include <stdio.h>
#include <stdlib.h>
int** createMatrix(int rows, int cols)
{
int i;
int** mat = malloc(sizeof(*mat)*rows);
for ( i = 0; i < rows; ++i )
mat[i] = malloc(sizeof(*mat[i])*cols);
return mat;
}
void readMatrix(int** mat, int rows, int cols)
{
int r;
int c;
for ( r = 0; r < rows; ++r )
for ( c = 0; c < cols; ++c )
scanf("%d", &mat[c][c]);
}
void deleteMatrix(int** mat, int rows)
{
int i;
for ( i = 0; i < rows; ++i )
free(mat[i]);
free(mat);
}
void multiplyMatrix (int **first, int **second, int **multiply,
int frows, int fcols, int scols)
{
int sum = 0;
int r;
int c;
int k;
for (r = 0; r < frows; r++) {
for (c = 0; c < scols; c++) {
sum = 0;
for (k = 0; k < fcols; k++) {
sum += first[r][k]*second[k][c];
}
multiply[r][c] = sum;
}
}
}
int main()
{
int m, n, p, q;
int r, c;
int **first, **second, **multiply;
printf("Enter the number of rows and columns of first matrix\n");
scanf("%d%d", &m, &n);
first = createMatrix(m, n);
printf("Enter the elements of first matrix\n");
readMatrix(first, m, n);
printf("Enter the number of rows and columns of second matrix\n");
scanf("%d%d", &p, &q);
if (n != p)
printf("Matrices with entered orders can't be multiplied with each other.\n");
else
{
second = createMatrix(p, q);
printf("Enter the elements of second matrix\n");
readMatrix(second, p, q);
multiply = createMatrix(m, q);
multiplyMatrix(first, second, multiply, m, n, q);
printf("Product of entered matrices:-\n");
for (r = 0; r < m; r++) {
for (c = 0; c < q; c++)
printf("%d\t", multiply[r][c]);
printf("\n");
}
deleteMatrix(multiply, m);
deleteMatrix(second, p);
}
deleteMatrix(first, m);
return 0;
}

Resources