Thread: Dynamical Matriz to solve Determinant, uknown error

  1. #1
    Registered User
    Join Date
    May 2012
    Posts
    6

    Dynamical Matriz to solve Determinant, uknown error

    So... i can compile the following code but it aborts right when we try to put the values typed into the matrix.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    void allocheckm(float **m){
        if(!m){
            puts("Error in allocating!");
            free(m);
            exit(1);
        }
    }
    
    
    void allocheckl(float *m){
        if(!m){
            puts("Error in allocating!");
            free(m);
            exit(1);
        }
    }
    
    
    void *mallocm(float **matrix, int x){
    
    
        int i;
    
    
        puts("Allocating...");
        matrix=(float**) malloc (x*sizeof(float*));
        allocheckm(matrix);
        for (i=0; i<x; i++){
            *(matrix+i) = (float *) malloc (x*sizeof(float));
            allocheckl(matrix[i]);
        }
        puts("Allocated!");
        system("PAUSE");
    }
    
    
    void *reallocm(float **matrix, int x){
    
    
        int i;
        matrix=NULL;
    
    
        matrix = (float**) realloc(matrix, x*sizeof(float*));
        allocheckm(matrix);
        for (i=0; i<x; i++)
            *(matrix+i) = (float*) realloc(matrix[i], x*sizeof(float));
            allocheckl(*(matrix+1));
    }
    
    
    void copymatrix(float **v, float **k, int size){
        int i, j;
        for (i=0;i<size;i++)
            for(j=0;j<size;j++)
                v[i][j]=k[i][j];
    }
    
    
    float determinant (float **v, int k) {
    
    
        float **d1, **d2;
        int i, j, l;
        int size, factor=1, det;
    
    
        for (i=0;i<k;i++){
            det=0;
            for(j=0;j<k;j++){
                if(v[i][j]!=0) det=1;
                if(v[j][i]!=0) det=1;
            }
            if(!det) break;
        }
    
    
        if (det){
            d1 = (float **) malloc (sizeof(float)*k);
            if(!d1) exit(1);
            d2 = (float **) malloc (sizeof(float)*(k-1));
            if(!d2) exit(1);
            copymatrix(d1, v, size);
            for    (size=k; size>1; size--) {
                if (d1[0][0]==0) {
                    for(i=1;i<size;i++)
                        if (d1[0][i]) break;
                    for(j=0;j<size;j++){
                        l=d1[j][0];
                        d1[j][0]=d1[j][i];
                        d1[j][i]=l;
                    }
                factor*=-1;
                }
                if (d1[0][0]!=1){
                    for(i=0;i<size;i++)
                        d1[0][i]/=d1[0][0];
                    factor*=(1/d1[0][0]);
                }
                for (i=0;i<(size-1);i++)
                    for(j=0;j<(size-1);j++)
                        d2[i][j]=(d1[i+1][j+1]-(d1[0][j]*d1[i][0]));
                d1=(float **) realloc(d1, sizeof(float)*(size-1));
                if(!d1) exit(1);
                copymatrix(d1, d2, (size-1));
                d2=(float **) realloc(d2, sizeof(float)*(size-2));
                if(!d2) exit(1);
            }
        }
        det=d1[0][0]*factor;
        free(d1);
        free(d2);
        return det;
    }
    
    
    void readmat(float **v, int k) {
    
    
        int i, j, a=0;
        float l;
        puts("Type the matrix:");
        for (i=0;i<k;i++)
            for(j=0;j<k;j++) {
                scanf("%f", &l);
                a++;
                printf("\n%d values inserted.\b", a);
                v[i][j]=l;
            }
    
    
    }
    
    
    void showmat(float **v, int k) {
    
    
        int i, j;
        puts("Matrix:");
        for (i=0;i<k;i++)
            for(j=0;j<k;j++){
                printf("%f ", v[i][j]);
                if(j==2) printf("\n");
            }
    
    
    }
    
    
    int main() {
        float **mat;
        int size;
        float det;
        do {
            printf("Type size of the matriz: ");
            scanf("%d", &size);
            if (size<1) puts("Wrong size.");
        } while(size<1);
        mallocm (mat, size);
        if (!mat) exit(1);
        system("cls");
        int i, j, a=0;
        float l;
        readmat(mat, size);
        system("cls");
        showmat(mat, size);
        det=determinant(mat, size);
        printf("\n\ndet(M)=%d", det);
        free(mat);
        return 0;
    }
    i didn't have the time to test the determinant algorithm, but i was trying to archive it reducing the size of the matrix to 1. I know it is not the best way, but it is just trial. If i get this code running smooth, I will try to go for Laplace or reducing the matrix to a simpler one.

  2. #2
    Registered User
    Join Date
    May 2012
    Posts
    6
    sry, the last code had some orphans, this is the right one:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
     
     
    void allocheckm(float **m){
        if(!m){
            puts("Error in allocating!");
            free(m);
            exit(1);
        }
    }
     
     
    void allocheckl(float *m){
        if(!m){
            puts("Error in allocating!");
            free(m);
            exit(1);
        }
    }
     
     
    void mallocm (float **matrix, int x){
     
        int i;
     
        puts("Allocating...");
        matrix=(float**) malloc (x*sizeof(float*));
        allocheckm(matrix);
        for (i=0; i<x; i++){
            *(matrix+i) = (float *) malloc (x*sizeof(float));
            allocheckl(matrix[i]);
        }
        puts("Allocated!");
        system("PAUSE");
    }
     
     
    void reallocm(float **matrix, int x){
     
        int i;
        matrix=NULL;
     
        matrix = (float**) realloc(matrix, x*sizeof(float*));
        allocheckm(matrix);
        for (i=0; i<x; i++)
            *(matrix+i) = (float*) realloc(matrix[i], x*sizeof(float));
            allocheckl(*(matrix+1));
    }
     
    void copymatrix(float **v, float **k, int size){
        int i, j;
        for (i=0;i<size;i++)
            for(j=0;j<size;j++)
                v[i][j]=k[i][j];
    }
     
     
    float determinant (float **v, int k) {
     
     
        float **d1, **d2;
        int i, j, l;
        int size, factor=1, det;
     
     
        for (i=0;i<k;i++){
            det=0;
            for(j=0;j<k;j++){
                if(v[i][j]!=0) det=1;
                if(v[j][i]!=0) det=1;
            }
            if(!det) break;
        }
     
     
        if (det){
            d1 = (float **) malloc (sizeof(float)*k);
            if(!d1) exit(1);
            d2 = (float **) malloc (sizeof(float)*(k-1));
            if(!d2) exit(1);
            copymatrix(d1, v, size);
            for    (size=k; size>1; size--) {
                if (d1[0][0]==0) {
                    for(i=1;i<size;i++)
                        if (d1[0][i]) break;
                    for(j=0;j<size;j++){
                        l=d1[j][0];
                        d1[j][0]=d1[j][i];
                        d1[j][i]=l;
                    }
                factor*=-1;
                }
                if (d1[0][0]!=1){
                    for(i=0;i<size;i++)
                        d1[0][i]/=d1[0][0];
                    factor*=(1/d1[0][0]);
                }
                for (i=0;i<(size-1);i++)
                    for(j=0;j<(size-1);j++)
                        d2[i][j]=(d1[i+1][j+1]-(d1[0][j]*d1[i][0]));
                d1=(float **) realloc(d1, sizeof(float)*(size-1));
                if(!d1) exit(1);
                copymatrix(d1, d2, (size-1));
                d2=(float **) realloc(d2, sizeof(float)*(size-2));
                if(!d2) exit(1);
            }
        }
        det=d1[0][0]*factor;
        free(d1);
        free(d2);
        return det;
    }
     
     
    void readmat(float **v, int k) {
     
     
        int i, j, a=0;
        float l;
        puts("Type the matrix:");
        for (i=0;i<k;i++)
            for(j=0;j<k;j++) {
                scanf("%f", &l);
                a++;
                printf("\n%d values inserted.\b", a);
                v[i][j]=l;
            }
     
     
    }
     
     
    void showmat(float **v, int k) {
     
     
        int i, j;
        puts("Matrix:");
        for (i=0;i<k;i++)
            for(j=0;j<k;j++){
                printf("%f ", v[i][j]);
                if(j==2) printf("\n");
            }
     
    }
     
    int main() {
        float **mat;
        int size;
        float det;
        do {
            printf("Type size of the matriz: ");
            scanf("%d", &size);
            if (size<1) puts("Wrong size.");
        } while(size<1);
        mallocm (mat, size);
        if (!mat) exit(1);
        system("cls");
        readmat(mat, size);
        system("cls");
        showmat(mat, size);
        det=determinant(mat, size);
        printf("\n\ndet(M)=%d", det);
        free(mat);
        return 0;
    }
    note that, if you put the code block from the function inside the main function, it works....

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    1. Line 148 should be
    float **mat = NULL;

    2. if (!mat) exit(1);
    This should print an actual error message and then exit. Having the program exit with NO message at all is not very useful.

    Having done those things, you'll probably notice that it doesn't work at all, and always exits because mat is NULL.

    Do you understand why this code prints zero?
    Code:
    void foo ( int a ) {
      a = 42;
    }
    int main ( ) {
      int v = 0;
      foo(v);
      printf("%d\n", v );
      return 0;
    }
    When you know how to make this code print 42, you'll be able to fix your matrix allocation functions.

    Oh, and line 164 should call your freemat function.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Some tips:
    Line 48 is not in scope of the for-loop of line 46. You'd need braces around line 47-48.
    Line 92 needs an extra tab in front of it to indent it properly.
    You shouldn't be casting those calls to malloc or realloc. FAQ explains why.
    If you allocheck took a void*, then you wouldn't need two of that method.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  5. #5
    Registered User
    Join Date
    May 2012
    Posts
    6
    Quote Originally Posted by Salem View Post

    Do you understand why this code prints zero?
    Code:
    void foo ( int a ) {
      a = 42;
    }
    int main ( ) {
      int v = 0;
      foo(v);
      printf("%d\n", v );
      return 0;
    }
    I guess this way you pass only the value of the variable to the function but not it's index, so the function doesn't actually modify the value, but it creates another variable a.

    it should be like

    Code:
    #include <stdio.h>
    
    
    void foo ( int *a ) {
      *a = 42;
    }
    int main ( ) {
      int v = 0;
      foo(&v);
      printf("%d\n", v );
      return 0;
    }
    but I still don't know how it should help me dealing with matrix. I mean, when i declare float **mat, I am telling the program to create a pointer, so when I use the pointer in a function it doesn't need the &, because it is already passing the pointer index. That is my guess.

    That said, it is unclear to me why the mallocm function does not work the same way as readmat function does. If I allocate the matrix mat directly in main, not using another function, readmat works and I can print out the matrix I type.

    iMalc, i went to the FAQ and found some interesting infos about malloc and calloc, but nothing referring to multi casting these functions through defined functions...

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    OK, so having got as far as foo(&v) when trying to update an int (in main) from within a function, what do you think is more appropriate in your case?

    float **mat;
    allocm(mat);
    allocm(&mat);


    It doesn't matter what your variable type is, you still need "a pointer to it" if you want to update it. The fact that it has 1 or 2 stars in the declaration doesn't change that simple fact.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. creating dynamical output file names
    By mvanrijnbach in forum C++ Programming
    Replies: 3
    Last Post: 05-06-2010, 09:52 AM
  2. solve this error
    By moussa in forum C Programming
    Replies: 3
    Last Post: 05-28-2008, 05:38 AM
  3. dynamical data visualisation
    By joerg in forum C Programming
    Replies: 2
    Last Post: 10-12-2007, 12:35 PM
  4. error cant solve
    By developer47 in forum C Programming
    Replies: 1
    Last Post: 04-30-2007, 05:10 AM
  5. Odd error i cant solve
    By c++.prog.newbie in forum C++ Programming
    Replies: 0
    Last Post: 09-15-2005, 09:08 AM