Program with dynamic matrix crashes upon reaching printf - c

This program has some parts of it in spanish, so I'll explain: It's a dynamic 2D array, a message is printed to the user requesting the input of the number of rows and columns. Then the arrays get their space allocated using the function aloc, where calloc is used for the allocation, The second pointer receives the number of rows and then a for() cycle is used to allocate the space for the columns.
The problem arises in function imp(), which is supposed to print the resulting matrix, I believe it is due to the pointer arithmetic, but I'm unsure. The program crashes but there's no problem in the compilation process, and as far as I understand, all operations are valid.
I tried using the classic 2D array form, but it still crashes with a[i][j], insted of ((a+i)+j). I tried running the program without thhe printf, and it would crash upon reaching suma(), which is supposed to add both matrices, I believe it crashed when reaching the pointer arithmetic as well. When these were ommited, the program ran smoothly.
#include<stdio.h>
#include<stdlib.h>
#define p printf
#define s scanf
float** aloc(float **m,int r,int c);
void asig(float **a,int r,int c);
void imp(float **a,int r,int c);
float** suma(float **a,float **b,float **c,int r,int x);
int main(int argc,char*argv[])
{
float **ma=NULL,**mb=NULL,**mc=NULL;
int r=0,c=0,i=0,j=0;
p("\n\tEste programa suma 2 matrices cuyas dimensiones son dadas por el usuario\n\n\t%cCu%cntos renglones tienen las matrices?",168,160);
s("%d",&r);
p("\n\t%cCu%cntas columnas tienen las matrices?",168,160);
s("%d",&c);
ma=aloc(ma,r,c);
mb=aloc(mb,r,c);
mc=aloc(mc,r,c);
p("\n\n\t\tMATRIZ 1");
asig(ma,r,c);
imp(ma,r,c);
p("--------------------------\n\n\t\tMATRIZ 2");
asig(mb,r,c);
imp(mb,r,c);
p("--------------------------");
mc=suma(ma,mb,mc,r,c);
p("\n\tLa matriz resultante es:\n");
imp(mc,r,c);
fflush(stdin);
getchar();
return 0;
}
float** aloc(float **m,int r,int c)
{
int i=0;
if((m=(float**)calloc(r,sizeof(float*)))==NULL)
{
p("Error al asignar espacio");
exit(0);
}
for(i=0;i<r;i++)
if((m[i]=(float*)calloc(c,sizeof(float)))==NULL)
{
p("Error al asignar espacio");
exit(0);
}
return m;
}
void asig(float **a,int r,int c)
{
int i=0,j=0;
for(i=0;i<r;i++)
for(j=0;j<c;j++)
{
p("\n\t%cCu%cl es el elemento [%d][%d] de la matriz?",168,160,i+1,j+1);
s("%f",((a+i)+j));
}
}
void imp(float **a,int r,int c)
{
int i=0,j=0;
p("\n\tLa matriz queda:\n");
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
p("%f ",*(*(a+i)+j));
}
p("\n");
}
}
float** suma(float **a,float **b,float **c,int r,int x)
{
int i=0,j=0;
for(i=0;i<r;i++)
for(j=0;j<x;j++)
*(*(c+i)+j)=*(*(a+i)+j)+*(*(b+i)+j);
return c;
}de here

Here is the problem
s("%f", ((a + i) + j));
this
scanf("%f", &a[i][j]);
always use the proper function names, and this (*(a + i) + j) is also ok, but is confusing as you can see.
Use the array indexing notation to avoid problems.
If you want to know how I found it in the mess that you posted, I used compiler warnings. They are your friends.
BTW: scanf() has a return value, check it, if you accidentaly give the program some invalid input, then unexpected problems will happen, also for each malloc() you need a free() and don't use calloc() unless you intend to initialize the values to zero later, if you are going to initialize each value use malloc().
And here a corrected version of your program
#include <stdio.h>
#include <stdlib.h>
float** aloc(float **m,int r,int c);
void asig(float **a,int r,int c);
void imp(float **a,int r,int c);
float** suma(float **a,float **b,float **c,int r,int x);
int main()
{
float **ma = NULL,**mb = NULL,**mc = NULL;
int r = 0, c = 0;
printf("\n\tEste programa suma 2 matrices cuyas dimensiones son dadas por el usuario\n\n\t%cCu%cntos renglones tienen las matrices?",168,160);
if (scanf("%d", &r) != 1)
return -1;
printf("\n\t%cCu%cntas columnas tienen las matrices?", 168, 160);
if (scanf("%d", &c) != 1)
return -1;
ma = aloc(ma, r, c);
if (ma == NULL)
goto failed;
mb = aloc(mb, r, c);
if (mb == NULL)
goto failed;
mc = aloc(mc, r, c);
if (mc == NULL)
goto failed;
printf("\n\n\t\tMATRIZ 1");
asig(ma, r, c);
imp(ma, r, c);
printf("--------------------------\n\n\t\tMATRIZ 2");
asig(mb, r, c);
imp(mb, r, c);
printf("--------------------------");
mc = suma(ma, mb, mc, r, c);
printf("\n\tLa matriz resultante es:\n");
imp(mc, r, c);
getchar();
free(ma);
free(mb);
free(mc);
return 0;
failed:
free(ma);
free(mb);
free(mc);
return -1;
}
float** aloc(float **m,int r,int c)
{
int i = 0;
if ((m = calloc(r, sizeof(float*))) == NULL)
{
printf("Error al asignar espacio");
return NULL;
}
for (i = 0 ; i < r ; i++)
{
if ((m[i] = calloc(c, sizeof(float))) == NULL)
{
int j;
for (j = i ; j >= 0 ; j--)
free(m[j]);
free(m);
return NULL;
}
}
return m;
}
void asig(float **a,int r,int c)
{
int i = 0, j = 0;
for(i = 0 ; i < r ; i++)
{
for(j = 0 ; j < c ; j++)
{
printf("\n\t%cCu%cl es el elemento [%d][%d] de la matriz?", 168, 160, i + 1, j + 1);
scanf("%f", &a[i][j]);
}
}
}
void imp(float **a,int r,int c)
{
int i = 0,j = 0;
printf("\n\tLa matriz queda:\n");
for(i = 0 ; i < r ; i++)
{
for(j = 0 ; j < c ; j++)
{
printf("%10f", a[i][j]);
}
printf("\n");
}
}
float** suma(float **a,float **b,float **c,int r,int x)
{
int i = 0,j = 0;
for(i = 0 ; i < r ; i++)
{
for(j = 0 ; j < x ; j++)
{
c[i][j] = a[i][j] + b[i][j];
}
}
return c;
}

Related

Error when passing 2D array to function in c

I am writing a program to calculate matrix multiplication but it does not work. When I debug and check each value of the array a and b in function printMatrixMultiplication (which are entered by user), GDB prints out "cannot perform pointer math on incomplete type try casting". (I have searched for it but I still don't get it.) The function only works when the input is predefined in main.
This is my code
#include <stdio.h>
void input(int m, int n, double a[m][n]);
void output(int m, int n, double a[m][n]);
void printMatrixMultiplication(int row_a, int col_a, double a[row_a][col_a], int row_b, int col_b, double b[row_b][col_b]);
int main()
{
int row_a, col_a, row_b, col_b;
// get value of matrix a
printf("row_a = ");
scanf("%d", &row_a);
printf("col_a = ");
scanf("%d", &col_a);
double a[row_a][col_a];
input(row_a, col_a, a);
// output(row_a, col_a, a);
// get value of matrix b
printf("row_b = ");
scanf("%d", &row_b);
printf("col_b = ");
scanf("%d", &col_b);
double b[row_b][col_b];
input(row_b, col_b, a);
// output(row_b, col_b, a);
printMatrixMultiplication(row_a, col_a, a, row_b, col_b, b);
//test
// double a[2][2]={1,2,3,4};
// double b[2][3]={1,2,3,4,5,6};
// printMatrixMultiplication(2,2,a,2,3,b);
return 0;
}
void input(int m, int n, double a[m][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
scanf("%lf", &a[i][j]);
}
}
}
void output(int m, int n, double a[m][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%.2f ", a[i][j]);
}
printf("\n");
}
}
void printMatrixMultiplication(int row_a, int col_a, double a[row_a][col_a], int row_b, int col_b, double b[row_b][col_b])
{
if (col_a != row_b)
{
return;
}
double res[row_a][col_b]; //this matrix store results
for (int i = 0; i < row_a; i++) //the values be stored line by line, this
{ //operation is controled by i and j loops.
for (int j = 0; j < col_b; j++) //the k loop helps calculate dot_product.
{
double dot_product = 0;
for (int k = 0; k < col_a; k++)
{
dot_product += a[i][k] * b[k][j]; //ERROR HERE
}
res[i][j] = dot_product;
}
}
output(row_a, col_b, res);
}
So, where does the error come from and how to fix it?
Irrelevant, but the function is not well implemented so if possible, I would really appreciate if anyone gives me a hint to improve it.
I am using GCC version 6.3.0.
It's typo in your code when reading matrix b.
Just replace:
input(row_b, col_b, a);
with
input(row_b, col_b, b);

i have problem with acessing 2d array via function

i am learning pointers and i write these code to add two martix via function, it compile well and give correct answer for 2x2 matrix but for more than two row and col it fails when i try it with 3x3 matrix [0][0] element for the first matrix it automaticaly become 6 and [1][0] it became 9 every time, i can't figure out why this happen
#include <stdio.h>
//-----------------Function------------------
void add(int (*p1)[10], int (*p2)[10], int (*p3)[10], int r, int c);
void get(int (*p1)[10], int r, int c);
void print(int (*p1)[10], int r, int c);
//---------------Main Program----------------
int main()
{
//declartion
int i, j, r, c;
printf("\n\tenter the row and column of matrix\n\t");
scanf("%d %d", &r, &c);
int m1[r][c], m2[r][c], m3[r][c];
printf("\n\tenter the element of first matrix\n\t");
get(m1, r, c);
print(m1, r, c);
printf("\n\tenter the element of second matrix\n\t");
get(m2, r, c);
print(m2, r, c);
add(m1, m2, m3, r, c);
printf("\n");
print(m3, r, c);
return(0);
}
//-------------Define Function---------------
//get()
void get(int (*p1)[10], int r, int c)
{
int i, j;
for(i = 0; i < r; i++)
{
printf("\n\t");
for(j = 0; j < c; j++)
{
scanf("%d", (*(p1+i)+j));
}
}
}
//--------------------X----------------------
//add()
void add(int (*p1)[10], int (*p2)[10], int (*p3)[10], int r, int c)
{
int i, j;
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
//printf("\n%d %d = %d & %d", i, j, *(*(p1+i)+j), *(*(p2+i)+j));
*(*(p3+i)+j) = *(*(p1+i)+j) + *(*(p2+i)+j);
}
}
}
//--------------------X----------------------
//print()
void print(int (*p1)[10], int r, int c)
{
int i, j;
for(i = 0; i < r; i++)
{
printf("\n");
for (j = 0; j < c; j++)
{
printf("\t%d", *(*(p1+i)+j));
}
}
}
//--------------------X----------------------
Drop the array pointer notation and the fixed size. Use variable-length arrays based on the parameters.
Remove useless comments like // get ... void get...
Don't use unreadable de-referncing with *(arr+i) when you could be writing readable arr[i].
Print new line after each row, not before each row.
Here's a cleaned up program which compiles. I haven't tested it.
#include <stdio.h>
void add (int r, int c, int p1[r][c], int p2[r][c], int p3[r][c]);
void get (int r, int c, int p1[r][c]);
void print (int r, int c, int p1[r][c]);
int main (void)
{
int i, j, r, c;
printf("\n\tenter the row and column of matrix\n\t");
scanf("%d %d", &r, &c);
int m1[r][c], m2[r][c], m3[r][c];
printf("\n\tenter the element of first matrix\n\t");
get(r, c, m1);
print(r, c, m1);
printf("\n\tenter the element of second matrix\n\t");
get(r, c, m2);
print(r, c, m2);
add(r, c, m1, m2, m3);
printf("\n");
print(r, c, m3);
return(0);
}
void get (int r, int c, int p1[r][c])
{
for(int i = 0; i < r; i++)
{
for(int j = 0; j < c; j++)
{
scanf("%d", &p1[i][j]);
}
}
}
void add (int r, int c, int p1[r][c], int p2[r][c], int p3[r][c])
{
for(int i = 0; i < r; i++)
{
for(int j = 0; j < c; j++)
{
p3[i][j] = p1[i][j] + p2[i][j];
}
}
}
void print (int r, int c, int p1[r][c])
{
for(int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
printf("\t%d", p1[i][j]);
}
printf("\n");
}
}

c program run on codeblocks but not on clion how is it even possible?

i successfully run it on codeblocks, but my clion doesnt display anything when i run it.
i usually use clion, so im very furious about this. (dont want to be obligated to use codeblocks)
please help a poor lost soul.
this is the code.
dont have a lot more to say, but still stackoverflow wants me to write more, so here i am.
#include <stdio.h>
#include <stdlib.h>
int **malloc2dR(int r,int c);
int **MATinit(int r, int c);
void MATstampa(int **m, int r, int c);
void change(int **M, int r, int c);
int main() {
int r=3,c=4;
int **M=MATinit(r,c);
MATstampa(M,r,c);
change(M,r,c);
MATstampa(M,r,c);
return 0;
}
int **malloc2dR(int r, int c){
int **m;
int i;
m=malloc(r*sizeof (int *));
for(i=0;i<r;i++)
m[i]=malloc(c*sizeof (int));
return m;
}
int **MATinit(int r, int c){
int **M=malloc2dR(r,c);
int i,j;
printf("scrivere in input i valori della matrice %dx%d\n",r,c);
for(i=0;i<r;i++)
for(j=0;j<c;j++)
scanf("%d",&M[i][j]);
return M;
}
void MATstampa(int **m, int r, int c){
int i,j;
for(i=0;i<r;i++) {
for (j = 0; j < c; j++)
printf("%d ", m[i][j]);
printf("\n");
}
printf("\n");
}
void change(int **M, int r, int c) {
int i, j;
int ii, jj;
int **Mfake=malloc2dR(r,c);
for(i=0;i<r;i++)
for(j=0;j<c;j++)
Mfake[i][j]=M[i][j];
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
if (M[i][j] % 2 == 1) {
for (ii = 0; ii < r; ii++)
Mfake[ii][j] = 1;
for (jj = 0; jj < c; jj++)
Mfake[i][jj] = 1;
}
for(i=0;i<r;i++)
for(j=0;j<c;j++)
M[i][j]=Mfake[i][j];
}

Exception thrown at 0x00007FF93F57B016 (ucrtbased.dll) in Ficha 5.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF

I wrote some code and it showed me this error: Exception thrown at 0x00007FF93F57B016 (ucrtbased.dll) in Ficha 5.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
I can't find the reason behind it.
#include <stdio.h>
#define num 10
void ler_matriz(int **matriz1, int n, int m);
void mostrar_matriz(int matriz1[num][num], int n, int m);
//int num_min_matriz(int matriz1[][], int n, int m);
//void teste_simetria(int matriz1[][], int n, int m);
//void transposta_matriz(int matriz1[][], int n, int m);
//void soma_matriz(int matriz1[][], int matriz2[][], int matriz3[][], int n, int m);
int main()
{
int x[num][num], y[num][num], z[num][num], numL, numC;
printf("Introduza o número de linhas e colunas para a matriz:\n");
scanf(" %d%d", &numL, &numC);
printf("\n\nIntroduza os valores para a matriz 1: ");
ler_matriz(x, numL, numC);
mostrar_matriz(x, numL, numC);
return 0;
}
void ler_matriz(int **matriz1, int n, int m)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
printf("\nx[%d][%d]: ", i + 1, j + 1);
scanf(" %d", &matriz1[i][j]); // the exception error
}
}
}
void mostrar_matriz(int matriz1[num][num], int n, int m)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; i < m; j++)
{
printf("%d ", matriz1[i][j]);
}
putchar('\n');
}
}
You have:
for (int j = 0; i < m; j++)
This should be
for (int j = 0; j < m; j++)
Otherwise, i < m is going to be true forever (because you're not changing i in that loop) and you'll eventually be accessing 0xFFFFFFFFFFFFFFFF (the very edge of memory).
For memory errors like this a good idea is to use a memory checking tool (you can try valgrind memcheck). Now let's see what's wrong with your code :)
The array
You have to take into account that int[m][n] isn't the same as int**. Using the gcc compiler you'll get a warning about it. (Of course, you can alter your code to use int**)
The For Loop
Just as VoteyDisciple said you should be using
for (int j=0;j<m;j++)
instead of
for(int j=0;i<m;j++)
Uninitialized values
Creating an array and not initializing it can lead to memory errors later on (assuming we're talking about C - some languages initialize arrays with 0's). Here you create the x,y,z matrixes but you end up using a portion of them which you assign values to. The rest remain uninitialized and you can end up running into errors if you try accessing them later on.
The scanf exception
Really the exception you get is due to the above, as you're getting errors from trying to access the memory address at &matriz1[i][j]
Fixing it all
Here's how I'd write your code so that it works:
#include <stdio.h>
#include <stdlib.h>
#define num 10
void ler_matriz(int **matriz1, int n, int m);
void mostrar_matriz(int** matriz1, int n, int m);
//int num_min_matriz(int matriz1[][], int n, int m);
//void teste_simetria(int matriz1[][], int n, int m);
//void transposta_matriz(int matriz1[][], int n, int m);
//void soma_matriz(int matriz1[][], int matriz2[][], int matriz3[][], int n, int m);
int main()
{
//int x[num][num], y[num][num], z[num][num], numL, numC;
int i,j,**x,**y,**z,numL,numC; //Proper declarations
x=malloc(num*sizeof(int*));
y=malloc(num*sizeof(int*));
z=malloc(num*sizeof(int*));
for(i=0;i<num;i++) {
x[i]=malloc(num*sizeof(int));
y[i]=malloc(num*sizeof(int));
z[i]=malloc(num*sizeof(int));
}
//Initialization
for(i=0;i<num;i++) {
for(j=0;j<num;j++) {
x[i][j]=y[i][j]=z[i][j]=0;
}
}
printf("Introduza o número de linhas e colunas para a matriz:\n");
scanf(" %d%d", &numL, &numC);
printf("\n\nIntroduza os valores para a matriz 1: ");
ler_matriz(x, numL, numC);
mostrar_matriz(x, numL, numC);
for(i=0;i<num;i++) {
free(x[i]);
free(y[i]);
free(z[i]);
}
free(x);
free(y);
free(z);
return 0;
}
void ler_matriz(int **matriz1, int n, int m)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
printf("\nx[%d][%d]: ", i + 1, j + 1);
scanf(" %d", &matriz1[i][j]);
}
}
}
void mostrar_matriz(int **matriz1, int n, int m)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
printf("%d ", matriz1[i][j]);
}
putchar('\n');
}
}

Function Does nothing

I can't make the function mostrarmatriz() work. The program does compile and run from beginning to end without errors, but the function mostrarmatriz() doesn't show up anything. When I copy that function into the main function it works perfectly. It seems I'm having a problem passing the values by reference. Please help, I'm stuck.
Main.c File:
#include "InvMatriz.h"
#include <stdio.h>
int main(int argc, char **argv)
{
float **A;
int n;
printf("Ingrese el tamaño de la matriz: ");
scanf("%d", &n);
A = ingresematriz(n);
void mostrarmatriz(A, n);
printf("adfasd");
return 0;
}
Header File InvMatriz.h
#ifndef INVMATRIZ_H_
#define INVMATRIZ_H_
float** ingresematriz(int );
void mostrarmatriz(float**X ,int x);
#endif // INVMATRIZ_H
Ingrese Matriz.c File
#include "InvMatriz.h"
#include <stdio.h>
float **ingresematriz(int n)
{
int i, j;
//Asigna espacio en la memoria
float **A;
A = malloc(n * sizeof (float *));
for (i = 0; i < n; i++)
{
*(A + i) = malloc(n * sizeof(float));
}
//Pide los elementos y los guarda
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
printf("Elemento [%d] [%d]: ", i + 1, j + 1);
scanf("%f", *(A + i) + j);
}
}
return A;
}
Mostrar Matriz.c File
#include "InvMatriz.h"
#include <stdio.h>
void mostrarmatriz(float **X , int x) //Porque no hace nada pero si compila?
{
int i, j;
for (i = 0; i < x; i++)
{
for (j = 0; j < x; j++)
{
printf("%f ", *(*(X + i) + j));
}
printf("\n");
}
}
The line
void mostrarmatriz(A,n);
does not call mostrarmatriz, but it declares a function void mostrarmatriz(int,int) (the int type for the arguments is the old "implicit int" rule). Remove the void in that line, and your function will be called.
If you compiled your code with warnings, your compiler would have told you.

Resources