将二维数组作为参数传递给函数并获取另一个二维数组

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

我正在编写一个代码来计算给定矩阵的逆矩阵,问题是,我需要将其包含在其他代码中以进行统计拟合,所以我需要类似函数的东西来接收大小矩阵(矩阵是方阵)和矩阵本身以及 returns 他的逆矩阵,我发现了一些关于语法的东西然后有了这个 (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;//*
}

我把 //* 放在哪里是我有疑问的地方,语法是否正确?声明,在 return 中应该有其他东西,而不仅仅是 I?。当我编译时出现分段错误,按照 Taekahn 的建议,使用消毒剂编译 g++ -fsanitize=address -fsanitize=undefined -fsanitize=leak inverse.cpp 我得到

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

如果你能帮助我,我真的很感激,非常感谢你,非常感谢你在评论中的反馈,我是新来的,有问题。

更新:感谢 nasy 的回答,重要的是要注意很多人都提到了矢量方法,因此,对于阅读本文的任何人,请查看评论并更好地尝试矢量方法。

在你的第二个函数中,你有 float *I = 0。稍后,您尝试写入此数组但尚未分配它。您索引矩阵的方式是展平方法,因此您必须编写 float *I = new float[n*n]。当然有不同的方法,比如评论中提到的使用动态二维数组、二维向量等。

问题 是指针 I 没有指向任何对象,并且您有以下语句:

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

以上语句导致未定义的行为。想象一下当 ij 在第一次迭代中都是 0 时会发生什么。然后你取消引用 I 不指向任何 float 对象,因此这是未定义的行为。

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.

所以您看到(也许看到)的输出是未定义行为的结果。正如我所说,不要依赖具有 UB 的程序的输出。在您的情况下,程序可能会崩溃。

因此,使程序正确的第一步是删除 UB。 然后并且只有那时你可以开始对程序的输出进行推理。

此外,使用 std::vector 比使用 newdelete 进行手动内存管理更好。


1有关未定义行为的更技术准确的定义,请参阅 this 其中提到:没有对程序行为的限制.