是什么导致我的数组地址传递给函数时损坏(更改)?

问题描述 投票:0回答:1

我正在执行压缩的稀疏原始矩阵矢量乘法(CSR SPMV):这涉及将数组A分成多个chunks,然后通过引用将该块传递给一个函数,但是仅传递函数的第一部分数组(A [0]从数组开头开始的第一个块)被修改。但是,从第二个循环A [0 + chunkIndex]开始,当函数读取子数组时,尽管索引正确,但它会跳转并读取超出总数组地址范围的其他地址。

供参考:

enter image description here


SPMV 内核是:

void serial_matvec(size_t TS,  double *A, int *JA, int *IA,  double *X, double *Y)
{
    double sum;
    for (int i = 0; i < TS; ++i)
    {   
        sum = 0.0;
        for (int j = IA[i]; j < IA[i + 1]; ++j)
        {
                sum += A[j] * X[JA[j]]; // the error is here , the function reads diffrent 
                                        // address of A,  and JA, so the access 
                                       // will be out-of-bound
            }
            Y[i] = sum;
        }
    }

并且这样称呼:

int chunkIndex = 0;
for(size_t k = 0; k < rows/TS; ++k)
{
    chunkIndex = IA[k * TS];
    serial_matvec(TS, &A[chunkIndex], &JA[chunkIndex], &IA[k*TS], &X[0], &Y[k*TS]);
}

假设我处理((8x8)矩阵,并且我处理每个块2行,所以循环k将是r ows / TS = 4个循环,< [chunkIndex和传递给该函数的数组将如下所示:

chunkIndex:0->循环k = 0,&A [0],&JA [0]

chunkIndex:->循环k = 1,&A [16],&JA [16]

// [错误,函数读取了不同的地址]

chunkIndex:->循环k = 2,&A [32],&JA [32]

// [错误,函数读取了不同的地址]

chunkIndex:->循环k = 3,&A [48],&JA [48]

// [错误,函数读取了不同的地址]

当我运行代码时,只有第一个块正确执行,其他三个块内存被破坏,并且数组指针跳入超出数组大小的边界。

我已经手动检查了所有参数的所有索引,它们都是正确的,但是当我打印地址时,它们是不同的。 (现在将其调试3天)

我使用了valgrind,并报告:

大小8的无效读取

sum + = A [j] * X [JA [j]];行]中使用[[大小8的未初始化值的使用]]我用-g -fsanitize=address编译并得到

堆缓冲区溢出

我试图在函数外部手动访问这些块,它们是正确的,那么是什么会导致像这样破坏堆内存?

代码是here,这是我所能做的最低要求。

我正在执行压缩的稀疏原始矩阵向量乘法(CSR SPMV):这涉及将数组A划分为多个块,然后将该块通过引用传递给函数,但是仅...

c memory heap-memory
1个回答
0
投票
[[chunk
© www.soinside.com 2019 - 2024. All rights reserved.