2015-12-29 39 views
0

我随机创建了两个矩阵A0和A1,它们的大小是随机的。之后,我将这两个矩阵复制到A01矩阵,如删除2D指针矩阵时发生崩溃[检测到堆损坏]

[A0 | 0 ] 
[0 | A1] 

最后,我删除了它们的内存。不过,我只运行约3-5倍,在此之后,该方案如

enter image description here

我使用的Visual Studio 2015年什么是发生在我的代码检测错误?删除指针矩阵是错误的吗?

这是我的全码

#include <iostream> 
#include <stdlib.h> 
#include <time.h>  /* time */ 
#define random(x) (rand()%x) 
typedef unsigned char U8; 
typedef unsigned int U32; 
void create_and_delete_matrix() 
{ 
    U32 M0,M1,M01; 
    U32 m_L0,m_L1,m_L01; 
    U32 range = 20; 
    M0 = random(range) + 1; 
    m_L0 = random(range) + 1; 
    M1 = random(range) + 1; 
    m_L1 = random(range) + 1; 
    M01 = M0 + M1; 
    m_L01 = m_L0 + m_L1; 

    U8** A0 = new U8*[M0]; 
    U8** A1 = new U8*[M1]; 
    U8** A01 = new U8*[M01]; 
    //***********For A0***********// 
    for (U32 i = 0; i < M0; ++i){ 
     A0[i] = new U8[m_L0]; 
     memset(A0[i], 0, m_L0*sizeof(U8)); 
    } 
    //***********For A1***********// 
    for (U32 i = 0; i < M1; ++i) { 
     A1[i] = new U8[m_L1]; 
     memset(A1[i], 0, m_L1*sizeof(U8)); 
    } 
    //***********For A01***********// 
    for (U32 i = 0; i < M01; ++i) { 
     A01[i] = new U8[m_L01]; 
     memset(A01[i], 0, m_L01*sizeof(U8)); 
    } 

    //***********Set random data A0 and A1***********// 
    for (U32 i = 0; i < M0; ++i) { 
     for (U32 j = 0; j < m_L0; ++j) { 
      A0[i][j] = random(2); 
      printf("%d ", A0[i][j]); 
     } 
     printf("\n"); 
    } 
    for (U32 i = 0; i < M1; ++i) { 
     for (U32 j = 0; j < m_L1; ++j) { 
      A1[i][j] = random(2); 
      printf("%d ", A1[i][j]); 
     } 
     printf("\n"); 
    } 
    //***********Copy A0 and A1 to A01 ***********// 
    //***********--------------------- ***********// 
    //***********------[A0 | 0 ]-------***********// 
    //***********------[0 | A1]-------***********// 
    //***********--------------------- ***********// 
    for (U32 i = 0; i < M0; ++i){ 
     //A0 to A01 
     memcpy(A01[i] + m_L0, A0[i], m_L0 * sizeof(U8)); 
    } 
    for (U32 i = 0; i < M1; ++i){ 
     // A1 to A01 
     memcpy(A01[i + M0] + m_L0, A1[i], m_L1 * sizeof(U8)); 
    } 
    //**********Print result of A01**********// 
    for (U32 i = 0; i < M01; ++i) { 
     for (U32 j = 0; j < m_L01; ++j) { 
      printf("%d ", A01[i][j]); 
     } 
     printf("\n"); 
    } 

    //free A0, A1, A01 matrix 
    for (U32 i = 0; i < M0; ++i){ 
     if (i < m_L0){ 
      delete[] A0[i]; 
      A0[i] = NULL; 
     } 
    } 
    delete[] A0; 
    A0 = NULL; 

    for (U32 i = 0; i < M1; ++i) { 
     if (i < m_L1) { 
      delete[] A1[i]; 
      A1[i] = NULL; 
     } 
    } 
    delete[] A1; 
    A1 = NULL; 

    for (U32 i = 0; i < M01; ++i) { 
     if (i < m_L01) { 
      delete[] A01[i]; 
      A01[i] = NULL; 
     } 
    } 
    delete[] A01; 
    A01 = NULL; 

} 
int main(int argc, char **argv) { 
    unsigned int time_ui = static_cast<unsigned int>(time(NULL)); 
    srand(time_ui); 
    for (U32 iter = 0; iter < 100; iter++){ 
     create_and_delete_matrix(); 
    } 
    return 0; 
} 

这是live demo code

我在Ubuntu还测试使用g ++和误差是

*** Error in `main': free(): invalid next size (fast): 0x0000000001a58600 ***              
======= Backtrace: =========                          
/lib64/libc.so.6(+0x7850e)[0x7ff6e22d750e]                       
/lib64/libc.so.6(cfree+0x5b5)[0x7ff6e22e3165]                      
main[0x40107b]                              
main[0x401105]                              
/lib64/libc.so.6(__libc_start_main+0xf0)[0x7ff6e227efe0]                   
main[0x400939]                              
======= Memory map: ========                          
00400000-00402000 r-xp 00000000 fd:198 59464901       /home/cg/root/main           
00601000-00602000 r--p 00001000 fd:198 59464901       /home/cg/root/main           
00602000-00603000 rw-p 00002000 fd:198 59464901       /home/cg/root/main 
+0

你已经通过调试器中运行你的代码,对不对?另外,当你使用'new []'和'delete []'时,这或多或少是C99,而不是C++。 – Zeta

+0

是的。我通过Kdevelop运行visual Studio 2015和Ubuntu中的g ++调试 – Jame

+0

抱歉。我会清理它。但它仍然有错误 – Jame

回答

2

问题是在这里

for (U32 i = 0; i < M0; ++i){ 
    //A0 to A01 
    memcpy(A01[i] + m_L0, A0[i], m_L0 * sizeof(U8)); 
} 
for (U32 i = 0; i < M1; ++i){ 
    // A1 to A01 
    memcpy(A01[i + M0] + m_L0, A1[i], m_L1 * sizeof(U8)); 
} 

应该

for (U32 i = 0; i < M0; ++i){ 
    //A0 to A01 
    memcpy(A01[i], A0[i], m_L0 * sizeof(U8)); 
} 
for (U32 i = 0; i < M1; ++i){ 
    // A1 to A01 
    //After m_L0 elements 
    memcpy(A01[i] + m_L0, A1[i], m_L1 * sizeof(U8)); 
} 

或者你也可以复制单元方式,这将使其更具可读性。

此外,这里

for (U32 i = 0; i < M0; ++i){ 
    A0[i] = new U8[m_L0]; 
} 
for (U32 i = 0; i < M0; ++i){ 
    A0[i] = new U8[m_L0]; 
    memset(A0[i], 0, m_L0*sizeof(U8)); 
} 
//***********For A1***********// 
for (U32 i = 0; i < M1; ++i){ 
    A1[i] = new U8[m_L1]; 
} 
for (U32 i = 0; i < M1; ++i) { 
    A1[i] = new U8[m_L1]; 
    memset(A1[i], 0, m_L1*sizeof(U8)); 
} 

要创建内存泄漏。第一循环不是必需的。如果可能的话,使用初始化器初始化为0。

为了避免这里的内存管理,您可以使用std::vectorreserve

编辑 免费,必须补充你的配置:

for (U32 i = 0; i < M1; ++i) { 
    delete [] A0[i]; 
} 

delete [] A0; 
+0

是的。这是正确的。我错了将A0复制到A01。抱歉。我的免费矩阵功能如何? – Jame

+0

自由矩阵看起来不错,只需从0运行我到所需的限制,而不是如果检查循环内。 – doptimusprime

+0

你可以告诉我你的代码,它谈论“运行我从0到所需的限制,而不是如果检查循环内” – Jame

4

未定义行为由于重叠在/错误范围memcpy

请注意,您的代码或多或少是C,而不是C++。你可以让你的生活变得更加简单,如果你使用std::vector,例如:

typedef std::vector<U8>   vector_u8_t; 
typedef std::vector<vector_u8_t> matrix_u8_t; 

matrix_u8_t A0(M0, vector_u8_t(m_L0, 0)); // (*) 

标线为你做矩阵的所有的分配和初始化(除了随机值),你也不要不得不担心后来释放你的记忆。

它仍然不是一个适当的矩阵类,但它需要你的一些责任。