繁体   English   中英

C-检测到堆栈粉碎

[英]C - stack smashing detected

我需要实现矩阵A的非常简单的就地LU分解。我使用的是高斯消去法,我想用3x3矩阵对其进行测试。 问题是,我不断收到stack smashing错误,却不知道为什么。 我在代码中看不到任何问题,可以这样做。 你有什么主意吗?

问题可能出在分解因子模块中。


###My code:###
#include <stdio.h>

int main() {
    int n = 3; // matrix size

    int A[3][3] = {
        {1, 4, 7},
        {2, 5, 8},
        {3, 6, 10}
    };

    printf("Matrix A:\n");

    for( int i=0; i < n; i++ ) {
        for( int j=0; j < n; j++ ) {
            printf("%d ", A[i][j]);

            if ( j % 2 == 0 && j != 0 ) {
                printf("\n");
            }
        }
    }

    // FACTORIZATION    
    int k;
    int rows;
    for( k = 0; k < n; k++ ) {
        rows = k + k+1;
        A[rows][k] = A[rows][k]/A[k][k];
        A[rows][rows] = A[rows][rows] - A[rows][k] * A[k][rows];
        printf("k: %d\n", k);
    }

    printf("Matrix after decomp:\n");
    for( int i=0; i < n; i++ ) {
        for( int j=0; j < n; j++ ) {
            printf("%d ", A[i][j]);

            if ( j % 3 == 0 && j != 0 ) {
                printf("\n");
            }
        }
    }

    return 0;
}

您的错误很可能在这里:

rows = k + k+1;
A[rows][k] = A[rows][k]/A[k][k];
A[rows][rows] = A[rows][rows] - A[rows][k] * A[k][rows];

这意味着rows通过值1、3、5; 然后用于访问仅包含三个元素的数组。 实际上,那会溢出,因为其中唯一的有效偏移量是1。

编辑 :查看您的Matlab代码,它做的事情完全不同,因为rows = k + 1:nrows设置为一个小向量,然后它使用拼接矩阵,C并不支持它作为基元。 您将需要使用显式循环来重新实现该函数和矩阵乘法A(rows, k) * A(k, rows)

您原来的Matlab代码是(Matlab具有从1开始的索引):

for k = 1:n - 1
    rows = k + 1:n
    A(rows, k) = A(rows, k) / A(k, k)
    A(rows, rows) = A(rows, rows) - A(rows, k) * A(k, rows)
end

rows = k + 1:n这是因为它设置rows来表示一个范围。 表达式A(rows, k)实际上是对矩阵的矢量形切片的引用,并且Matlab可以将矢量除以标量。

在最后一行, A(rows, rows)是矩阵形状的切片,而A(rows, k) * A(k, rows)是矩阵乘法,例如,乘以维度(1,3)和(3 ,1)获得(3,3)之一。

在C语言中,您不能使用内置=/运算符来做到这一点。

C等效项是:

for ( int k = 0; k < n - 1; ++k )
{
// A(rows, k) = A(rows, k) / A(k, k)
    for ( int row = k + 1; row < n; ++row )
        A[row][k] /= A[k][k];

// A(rows, rows) = A(rows, rows) - A(rows, k) * A(k, rows)
     for ( int row = k + 1; row < n; ++row )
        for ( int col = k + 1; col < n; ++col )
            A[row][col] -= A[row][k] * A[k][col];
}

(免责声明:未经测试!)

第一部分很简单:向量中的每个值都被标量除。

但是,第二行更为复杂。 Matlab代码包括矩阵乘法和矩阵减法; 以及从矩阵中提取子矩阵的操作。 如果我们尝试将其直接翻译为C,则非常复杂。

我们需要使用两个嵌套循环来遍历行和列,以对方矩阵执行此操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM