Home > OS >  Passing 2D arrays as argument to a function and get another 2D array
Passing 2D arrays as argument to a function and get another 2D array

Time:04-25

I'm writing a code which calculates the inverse matrix given a matrix, the thing is, I need that to be included in other code that makes statistical fits, so I need something like a function that receives the size of the matrix (matrix is square matrix) and the matrix itself and returns his inverse, I found something about the syntax and then have this (Gauss-Jordan)

float* inv(int n, float *A)
{
    float* I = 0;//*

    float aux;
    float pivote;

    for(int i = 0; i<n; i  ){
        for(int j = 0; j<n; j  ){

            if(i == j)
            {
                *(I i*n j) = 1.0; //*
            }

            else {
                *(I i*n j) = 0.0;
            }
        }
    }

    for(int i = 0; i<n; i  )
    {
        pivote = *(A i*n i);

        for(int k = 0; k<n; k  )
        {
            *(A i*n k) = *(A i*n k)/pivote;//*
            *(I i*n k) = *(I i*n k)/pivote;//*
        }

        for(int j = 0; j<n; j  )
        {
            if(i!=j)
            {
                aux = *(A j*n i);//*

                for(int k = 0; k<n;k  )
                {
                    *(A j*n k)=*(A j*n k)-aux**(A i*n k);//*
                    *(I j*n k)=*(I j*n k)-aux**(I i*n k);//*
                }
            }
        }
    }

    return I;//*
}

There where I put the //* is where I have my doubts, is the syntax correct? the declarations, there in the return should be something else than just I?. When I compile I get a segmentation fault, Following Taekahn recommendations, compiling with sanitizers g -fsanitize=address -fsanitize=undefined -fsanitize=leak inverse.cpp I get

inverse.cpp:148:28: runtime error: store to null pointer of type 'float'
AddressSanitizer:DEADLYSIGNAL
=================================================================
==11993==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x00000040338c bp 0x7ffdd6a14510 sp 0x7ffdd6a144b0 T0)
==11993==The signal is caused by a WRITE memory access.
==11993==Hint: address points to the zero page.
    #0 0x40338b in inv(int, float*) (/home/live/med_elect/a.out 0x40338b)
    #1 0x402f30 in main (/home/live/med_elect/a.out 0x402f30)
    #2 0x7f90ffed9e5a in __libc_start_main (/lib64/libc.so.6 0x23e5a)
    #3 0x402289 in _start (/home/live/med_elect/a.out 0x402289)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/home/live/med_elect/a.out 0x40338b) in inv(int, float*)
==11993==ABORTING

I really appreciate if you can help me, thank you very much in advance and thank you very much for the feedback in the comments, I'm new here with the questions.

UPDATE: Thanks to nasy for the answer, It is important to note that many people mentioned the vector approach, so, to anyone reading this, check the comments and better try the vector approach.

CodePudding user response:

In your second function, you have float *I = 0. Later on, you try to write to this array but you have not allocated it. The way you're indexing your matrices is the flattening approach so you must write float *I = new float[n*n]. There are different approaches, of course, like using dynamic 2D arrays, 2D vectors, etc. as mentioned in the comments.

CodePudding user response:

The problem is that the pointer I doesn't point to any object and you've the following statement:

*(I i*n j) = 1.0; //undefined behavior

The above statement leads to undefined behavior. Imagine what happens when i and j are both 0 in the first iteration. Then you're dereferencing I which doesn't point to any float object and thus this is undefined behavior.

Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior. The program may just crash.

So the output that you're seeing(maybe seeing) is a result of undefined behavior. And as i said don't rely on the output of a program that has UB. The program may just crash which happens in your case.

So the first step to make the program correct would be to remove UB. Then and only then you can start reasoning about the output of the program.

Also, it would be better to use std::vector than doing manual memory management using new and delete.


1For a more technically accurate definition of undefined behavior see this where it is mentioned that: there are no restrictions on the behavior of the program.

  • Related