Getting glibc detected error when trying to delete parts of a matrix in C++
When I run the following code, I keep getting a glibc detected error when I try to use the delete[] I[i] command (always on the last run through of the loop). Right before the loop that tries to delete I[i], I print out the values in the last row of I, and it shows up exactly as it is supposed to, so I don't think the issue has to do with the loop being too large. What am I doing wrong? (I've included every line of code where **I shows up).
EDIT 2: The entirety of the error message is:
*** 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/cmo开发者_StackOverflow中文版v/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
EDIT: I've changed it to include the entirety of the code.
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
}
I really find this way of allocating 2-D matrices annoying, so I wrote a simple C procedure to allocate and initialize a 2-D array with a single malloc() call, so you can release the memory with a single free() call. (Note, this could be extended/modified to use new 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;
}
Then you could create each of your matrices using the single line, e.g.:
double** I = (double**)matrix2D(size, size, sizeof(double));
and they could be freed using, e.g.:
free(I);
Much simpler. Also, then the matrix data values are contiguous, so for example if you create an array of integers and you want to initialize them all to zero, you could do:
int** array = (int**)matrix2D(height, width, sizeof(int));
memset(array, 0, height * width * sizeof(int));
or, to initialize it to a given (non-zero) value:
for (int i = 0; i < height * width; ++i)
array[i] = value;
精彩评论