Salvador Villarreal
Salvador Villarreal

Reputation: 13

Program with dynamic matrix crashes upon reaching printf

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

Upvotes: 1

Views: 90

Answers (1)

Iharob Al Asimi
Iharob Al Asimi

Reputation: 53006

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

Upvotes: 1

Related Questions