如何删除完整的2D指针数组

时间:2015-12-31 07:02:46

标签: c++ arrays pointers

我在C ++中有一个2D指针矩阵,例如,

typedef unsigned char  U8;
typedef unsigned int   U32;
int M=10;
int m_L=8;
U8** A = new U8*[M];
for (U32 i = 0; i < M; ++i)
{
    A[i] = new U8[m_L];
}

在A0中设置值后,我会编写一个函数来决定删除或不删除A中的M-2行,取决于随机数是0还是1

void delete_or_not(U8** A,int M) 
{
  if (rand_num==1){
     for (U32 index = M-2; index < M; ++index){
        delete[] A[index];
     }
  }
}

现在,在main函数(包含A内存分配)中,我想释放/删除为A分配的内存。我可以使用代码

//free A matrix
for (U32 i = 0; i < M; ++i)
{
    if (i < m_L)
    {
      delete[] A[i];
      A[i] = NULL;
    }
}
delete[] A;
A = NULL;

我的问题是,我不知道A是删除(M-2)行还是没有。因此,如果我的随机数为0,上面的代码确实删除了所有内存。这意味着,如果在delete_or_not函数中删除了M-2行,则上面的代码只删除正确的内存。如何完美地删除A​​矩阵。感谢

最后,我的完整代码是

typedef unsigned char  U8;
typedef unsigned int   U32;
int M=10;
int m_L=8;
U8** A = new U8*[M];
for (U32 i = 0; i < M; ++i)
{
    A[i] = new U8[m_L];
}
delete_or_not(A,M);
//free A matrix 
//Way 1: will miss M-2 row if delete_or_not function did not delete 2 rows.
// It only correct if rand_num=1
for (U32 i = 0; i < M; ++i)
{
    if (i < m_L)
    {
      delete[] A[i];
      A[i] = NULL;
    }
}
delete[] A;
A = NULL;

//Way 2- It will correct if the size of A is M by M

for (U32 i = 0; i < M; ++i)
{
      delete[] A[i];
      A[i] = NULL;
}
delete[] A;
A = NULL;

2 个答案:

答案 0 :(得分:4)

只需将已删除的元素设置为NULL,一切都会正常运行:

void delete_or_not(U8** A,int M) 
{
  if (rand_num==1){
     for (U32 index = M-2; index < M; ++index){
        delete[] A[index];
        A[index] = NULL;
     }
  }
}

此外,这不是很有用:

for (U32 i = 0; i < M; ++i)
{
    if (i < m_L)
    {
      delete[] A[i];
      A[i] = NULL;
    }
}

如果你那时只做“工作”,那么i从0推进到M就没有意义了。当i小于m_L时。

但实际上,在C ++中,您应该使用std::vector<std::vector<U8>>代替erasepop_back来摆脱&#34;行&#34;。

答案 1 :(得分:1)

void delete_or_not中,您应将已删除的元素设置为NULL,如Amit的另一个答案所提议的那样。

然后,在两种情况下,您发布的代码的方式2都是正确的。

在NULL上调用delete是完全合法的,并且完全不会受到伤害。

方式1不起作用,应该删除。

总结:

void delete_or_not(U8** A,int M) 
{
  if (rand_num==1){
     for (U32 index = M-2; index < M; ++index){
        delete[] A[index];
        A[index] = NULL;    // Add this to your code
     }
  }
} 


// In main somewhere...

// free A
for (U32 i = 0; i < M; ++i)
{
      delete[] A[i];   // Not a problem if the element has already been deleted
                       // because the pointer will be NULL and calling
                       // delete with NULL is OK (and changes nothing)
      A[i] = NULL;
}
delete[] A;
A = NULL;