malloc导致嵌入式系统崩溃

3
我正在尝试在Cortex M4核心上对任意大小的矩阵进行乘法运算。我确实需要一个malloc……但是我不明白为什么第一次调用可以正常工作,而第二次调用就不能再工作了。它只会跳转到默认的中断处理程序FaultISR。
以下是反汇编代码: enter image description here 执行BL命令时出现错误。
函数调用:
multiplyMatrices( &transFRotMatrix[0][0],3, 3, &sunMeasurements[0][0], 3, 1, *orbitalSunVector); //Works fine

multiplyMatrices( &firstRotMatrix[0][0],3, 3, &orbitalTMFV[0][0], 3, 1, *inertialTMFV); //doesn t work fine

代码:

void multiplyMatrices(float *transposedMatrix, int height1, int width1, float *iSunVector,int height2, int width2, float *orbitalSunVector)
{

    int y=0;
    int x = 0;
    int row=0;
    int column =0;
    int k=0;
    int k2=0;
    float result = 0;
    float *output2=NULL;

    int i=0;
    int j=0;

    i=0;
    k=0;
    k2 = 0;


    if(width1 != height2)
    {
        //printf("unmatching matrices, error.\n\n");
        return;
    }

    output2 = malloc(height1 * width2 * sizeof(float)); //<---- jumps o FaultISR


    while(k<width1) //aantal rijen 1ste matrix
    {
        for(j=0;j<height2;j++) //aantal rijen 2de matrix
        {
            result += (*((transposedMatrix+k*width1)+j)) * (*((iSunVector+j*width2)+k2));  //1ste var:aantal kolommen 2de matrix  --2de variabele na de plus = aantal kolommen 2de matrix
            //printf("%f * %f\t + ", (*((transposedMatrix+k*width1)+j)), (*((iSunVector+j*width2)+k2)));
        }

         output2[row* width1 + column] = result;

        k2++;
        x++;
        column++;

        if(x==width2) //aantal kolommen 2de Matrix
        {
            k2=0;
            x=0;
            column=0;
            row++;
            y++;
            k++;
        }
        result = 0;

    }

    //tussenresultaat
    for(i=0;i<height1;i++)
    {
        for(j=0;j<width2;j++)
        {
             orbitalSunVector[j * height1 + i] = output2[i* width1 + j]; //output2[i][j];

        }
    }

    free(output2);
}

2
height1width2的值是多少?可能是因为内存不足了吗?也许是您在超出分配的内存结束(或其他某些)写入了数据? - Some programmer dude
除非堆栈和堆设置不正确,否则不应该失败,即使height1和width2太大,它也应该返回NULL(如果它们的乘积为负数,则情况相同)。 - theadnangondal
1
你可以在函数调用时查看这些变量的值。 - user4690356
1
因为这不是动态的,所以无法适用于任何大小的矩阵。 - user4690356
你的FaultISR中是否有任何标志可以告诉你它为什么会跳转到那里?很可能是内存不足,但了解原因会更好。另外,你使用的编译器是什么? - Gauthier
显示剩余11条评论
2个回答

0

由于索引计算不正确,您在两个循环中都溢出了output2矩阵。您有:

output2[row*width1 + column] = result;
...
orbitalSunVector[j*height1 + i] = output2[i*width1 + j];

但是在这两种情况下,你应该使用width2,因为最终的矩阵大小为width2 * height1(因为它已经被分配了):

output2[row*width2 + column] = result;
...
orbitalSunVector[j*height1 + i] = output2[i*width2 + j];

我没有检查你的其他索引,但我会测试一下该函数的几个已知案例,以确保它输出正确的结果。如果你进行了更多的调试并检查了数组索引,那么应该很容易发现。

请注意,它第一次工作但第二次不工作的原因是由于未定义行为(UB)。一旦你在output2的末尾写入,就会调用UB,任何事情都可能发生。对于你来说,这在第二次调用时出现了故障。对我来说,它在第一次调用时出现了故障。如果你非常不幸,它可能永远不会出现故障,只会悄悄地破坏数据。


我进行了更改,但不幸的是,这并没有解决我的问题,我错了。 - user4690356
如果您同意这里建议的更改,请相应地更新您问题中的代码。 - Gauthier
@rudolf,那么你很可能在其他地方也溢出了另一个缓冲区。(例如,请检查orbitalSunVector是否与代码所假定的一样大)。但请注意,即使崩溃发生在此函数中,很可能是由于堆的损坏引起的,错误可能是在其他地方引起的。 - nos
@rudolf 我也认为 @uesp有一些怀疑你的索引存在问题,我也有同感。你有相当数量的变量,名称不是非常描述性的。kk2xrowcolumn,这并不是很清楚它们是什么,以及它们适用于哪些矩阵或维度。我本来想重构你的函数,但这确实是你自己需要做的事情,例如从1xN乘以Nx1向量乘法中分离出一个单独的函数开始。 - Gauthier

0

你的代码中其他地方使用了printf吗?

这个页面建议从0x400开始设置堆大小,即1024十进制:

当代码中有限制动态分配(如printf()调用)时,建议从合理的堆大小(如0x400)开始,并根据应用程序需要适当增加。

你现在有512,如果可能的话,至少可以尝试按照TI的建议将其加倍,看看会发生什么。

这是一个相关的问题。如果你没有工具来实时监视堆分配,请尝试在启动时手动填充堆(使用已知值,如ASCII“#==#”、0xDEADBEEF或其他可识别的值进行memcpy),然后运行到通常崩溃之前,并在内存窗口中观察堆的内容。我最好的猜测是堆已经满了。

请在FaultISR中查看是否可以看到错误标志寄存器。通常会有某些东西告诉你为什么会来到这里。

我不确定TI的malloc实现,但他们可能会保存一个错误值。我不会把赌注压在那个上面,因为在那种情况下它可能会返回NULL,而不是崩溃。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接