将2D数组作为参数传递给函数,然后获得另一个2D数组

发布于 2025-01-24 06:33:25 字数 2308 浏览 3 评论 0原文

我正在编写一个计算给定矩阵的反向矩阵的代码,事实是,我需要将其包含在使统计拟合的其他代码中,因此我需要像接收矩阵大小的函数一样(矩阵是Square Matrix)和矩阵本身并返回他的倒数,我发现了有关语法的一些内容,然后

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

在我放置//*的地方(Gauss-Jordan)是我怀疑的地方,是语法正确吗?声明,退货中应该还有其他东西,而不仅仅是i?当我编译时,我会得到一个细分故障,按照泰昂的建议,使用消毒剂g ++ -fsanitize = address = address -fsanitize = undefined -fsanitize = undefined -fsanitize = elev inverse.cpp.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的答案,重要的是要注意,许多人提到了矢量方法,因此,对于任何阅读本文的人,检查评论并更好地尝试了矢量方法。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一场信仰旅途 2025-01-31 06:33:25

在您的第二个功能中,您具有float *i = 0。稍后,您尝试写入此数组,但您没有分配它。索引矩阵的方式是扁平的方法,因此您必须编写float *i = new Float [n *n]。当然,有不同的方法,例如使用动态2D数组,2D向量等。如评论中所述。

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.

§普罗旺斯的薰衣草 2025-01-31 06:33:25

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

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

上述语句导致不确定的行为 。想象一下,当iJ都是0时,会发生什么。然后,您要删除i,它没有指向任何float对象,因此这是不确定的行为。

未定义的行为意味着任何事物 1 可能发生,包括但不限于 提供了预期的输出。但是,永远不要依靠(或基于结论),这是基于具有不确定行为的程序的输出。该程序可能只是崩溃。

因此,您看到的(也许看到)的输出是不确定行为的结果。正如我所说,不依赖具有UB程序的程序的输出。该程序可能只是在您的情况下崩溃。

因此,使程序正确的第一步是删除UB。 然后,只有这样,您才能开始对程序的输出进行推理。

另外,使用std :: vector要比使用delete进行手动存储器管理要好。


1 有关未定义行为的更精确的定义,请参见 提到的地方:对程序的行为没有任何限制

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文