c++ - 尝试在 C++ 中删除矩阵的一部分时获取 glibc 检测到错误

标签 c++ glibc

当我运行以下代码时,当我尝试使用 delete[] I[i] 命令时(总是在循环的最后一次运行时),我不断收到 glibc 检测到的错误。在尝试删除 I[i] 的循环之前,我打印出 I 最后一行的值,它完全按照预期显示,所以我认为问题与循环无关太大了。我究竟做错了什么? (我已经包含了 **I 出现的每一行代码)。

编辑 2:错误消息的全部内容是:

*** glibc detected *** getParams: free(): invalid next size (fast): 0x086861f0 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(+0x6b591)[0x271591]
/lib/tls/i686/cmov/libc.so.6(+0x6cde8)[0x272de8]
/lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0x275ecd]
/usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0x1cb741]
/usr/lib/libstdc++.so.6(_ZdaPv+0x1d)[0x1cb79d]
getParams[0x804ac78]
getParams[0x8048943]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0x21cbd6]
getParams[0x8048731]
======= Memory map: ========
00110000-001f9000 r-xp 00000000 08:01 396979     /usr/lib/libstdc++.so.6.0.13
001f9000-001fa000 ---p 000e9000 08:01 396979     /usr/lib/libstdc++.so.6.0.13
001fa000-001fe000 r--p 000e9000 08:01 396979     /usr/lib/libstdc++.so.6.0.13
001fe000-001ff000 rw-p 000ed000 08:01 396979     /usr/lib/libstdc++.so.6.0.13
001ff000-00206000 rw-p 00000000 00:00 0 
00206000-00359000 r-xp 00000000 08:01 11272305   /lib/tls/i686/cmov/libc-2.11.1.so
00359000-0035a000 ---p 00153000 08:01 11272305   /lib/tls/i686/cmov/libc-2.11.1.so
0035a000-0035c000 r--p 00153000 08:01 11272305   /lib/tls/i686/cmov/libc-2.11.1.so
0035c000-0035d000 rw-p 00155000 08:01 11272305   /lib/tls/i686/cmov/libc-2.11.1.so
0035d000-00360000 rw-p 00000000 00:00 0 
0074f000-00773000 r-xp 00000000 08:01 11272350   /lib/tls/i686/cmov/libm-2.11.1.so
00773000-00774000 r--p 00023000 08:01 11272350   /lib/tls/i686/cmov/libm-2.11.1.so
00774000-00775000 rw-p 00024000 08:01 11272350   /lib/tls/i686/cmov/libm-2.11.1.so
00a7b000-00a7c000 r-xp 00000000 00:00 0          [vdso]
00d1c000-00d37000 r-xp 00000000 08:01 11276409   /lib/ld-2.11.1.so
00d37000-00d38000 r--p 0001a000 08:01 11276409   /lib/ld-2.11.1.so
00d38000-00d39000 rw-p 0001b000 08:01 11276409   /lib/ld-2.11.1.so
00ec8000-00ee5000 r-xp 00000000 08:01 11272275   /lib/libgcc_s.so.1
00ee5000-00ee6000 r--p 0001c000 08:01 11272275   /lib/libgcc_s.so.1
00ee6000-00ee7000 rw-p 0001d000 08:01 11272275   /lib/libgcc_s.so.1
08048000-0804c000 r-xp 00000000 08:01 4720134    /home/rkappiyo/Dropbox/xingResearch/finalMatlab/getParams
0804c000-0804d000 r--p 00003000 08:01 4720134    /home/rkappiyo/Dropbox/xingResearch/finalMatlab/getParams
0804d000-0804e000 rw-p 00004000 08:01 4720134    /home/rkappiyo/Dropbox/xingResearch/finalMatlab/getParams
08686000-086a7000 rw-p 00000000 00:00 0          [heap]
b7600000-b7621000 rw-p 00000000 00:00 0 
b7621000-b7700000 ---p 00000000 00:00 0 
b774f000-b7751000 rw-p 00000000 00:00 0 
b7762000-b7765000 rw-p 00000000 00:00 0 
bfcd4000-bfce9000 rw-p 00000000 00:00 0          [stack]
Aborted

编辑:我已将其更改为包含全部代码。

void invertMatrix(double **mat, int size) {
//index variables used for looping
int i, j, k;

//L and U are the LU decomposition of mat
double **L, **U;

//invMat is the inverted matrix, which will be stored in mat
double **invMat;

//I is the identity matrix
double **I;

L = new double *[size]; //allocation 1

for(i = 0; i < size; i++)
    L[i] = new double[size]; //allocation 2

U = new double *[size]; //allocation 3

for(i = 0; i < size; i++)
    U[i] = new double[size]; //allocation 4

//compute the LU decomposition of mat and store in L and U
LUDecomp(mat, size, L, U);

invMat = new double *[size]; //allocation 5

for(i = 0; i < size; i++)
    invMat[i] = new double [size]; //allocation 6

I = new double *[size]; //allocation 7

for(i = 0; i < size; i++) {
    I[i] = new double [size]; //allocation 8

    for(j = 0; j < size; j++) {
        if(i == j)
            I[i][j] = 1;
        else
            I[i][j] = 0;
    }
}

for(i = 0; i < size; i++) {
    invMat[i][0] = I[i][0] / L[0][0];

    for(j = 1; j < size; j++) {
        invMat[i][j] = I[i][j];

        for(k = 0; k < j; k++)
            invMat[i][j] -= L[j][k] * invMat[i][k];

        invMat[i][j] /= L[j][j];
    }
}

for(i = 0; i < size; i++) {
    mat[i][size - 1] = invMat[i][size - 1] / U[size - 1][size - 1];

    for(j = size - 2; j > -1; j--) {
        mat[i][j] = invMat[i][j];

        for(k = j + 1; k < size; k++)
            mat[i][j] -= U[j][k] * mat[i][k];

        mat[i][j] /= U[j][j];
    }
}

for(i = 0; i < size; i++) {
    delete[] L[i]; //free allocation 2
    delete[] U[i]; //free allocation 4
    delete[] invMat[i]; //free allocation 6
    delete[] I[i]; //free allocation 8
}

delete[] L; //free allocation 1
delete[] U; //free allocation 3
delete[] invMat; //free allocation 5
delete[] I; //free allocation 7
}

最佳答案

我真的觉得这种分配二维矩阵的方式很烦人,所以我写了一个简单的 C 程序来分配和初始化一个二维数组,只需调用一次 malloc(),这样你就可以用一个 free 释放内存() 称呼。 (注意,这可以扩展/修改为使用新的 char[...])

/* set up the memory for a 2D matrix with entries of size "size" */
void** matrix2D(long rows, long columns, long size)
{
    long    i;
    unsigned long long      row_size = (unsigned long long)columns * (unsigned long long)size;
    unsigned long long      data_size = ((unsigned long long)rows * (unsigned long long)columns + 1) * (unsigned long long)size;
    unsigned long long      pointer_size = (unsigned long long)rows * sizeof(void*);
    void**  result;

    if ( (result = (void**)malloc((size_t)(data_size + pointer_size))) == NULL ) {
            return NULL;
    }

    // take the first bit for a vector pointing to the m_pData for each row
    char* pdata = (char*)result + pointer_size;
    if ((unsigned long)pdata % size) {
      pdata += size - (unsigned long)pdata % size;
    }

    // for each row, set up the pointer to its m_pData
    for (i = 0; i < rows; i++) {
            result[i] = (void*)pdata;
            pdata += row_size;
    }

    return result;
}

然后您可以使用单行创建每个矩阵,例如:

double** I = (double**)matrix2D(size, size, sizeof(double));

它们可以被释放,例如:

free(I);

简单多了。此外,矩阵数据值是连续的,因此例如,如果您创建一个整数数组并希望将它们全部初始化为零,您可以这样做:

int** array = (int**)matrix2D(height, width, sizeof(int));
memset(array, 0, height * width * sizeof(int));

或者,将其初始化为给定的(非零)值:

for (int i = 0; i < height * width; ++i)
    array[i] = value;

关于c++ - 尝试在 C++ 中删除矩阵的一部分时获取 glibc 检测到错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4952034/

相关文章:

c - libc_hidden_​​builtin_def (strspn) 是什么意思?

c++ - 为什么 jeprof 评估的 jemalloc 内存配置文件似乎显示所有内存分配?

c++ - 在 Makefile 中解决依赖关系的常用方法是什么?

c - 多字节语言环境中 glibc 的 printf 截断错误的解决方法?

c - 重定向断言失败消息

posix - 当给定一个包含无法识别的可执行魔数(Magic Number)的文件时,posix_spawn() 应该如何表现?

c++ - 从 `binding` 到 `VkVertexInputBindingDescription` 的目的是什么?

c++ - 如果 printf ("%c%c",'A' ,8);删除A,为什么不能printf ("%c%c",'\n' ,8);删除新行?我该怎么做?

c++ - 使用 g++ 从 [-Wdangling-reference] 可能出现误报

linux - 符号 errno,版本 GLIBC_2.0 未定义,在 opensuse Linux 11.4 中