【问题标题】:Is it necessary to null your pointers after deleting multidimensional dynamic array删除多维动态数组后是否需要清空指针
【发布时间】:2020-12-06 12:11:45
【问题描述】:

我正在努力避免内存不足,我需要了解是否需要将 nullpointer 设置为我的 删除数组后的多维动态数组。这是我的代码。

int*** arr = new int** [lists];

for (int i = 0; i < lists; i++)
{
    arr[i] = new int* [row];
    for (int r = 0; r < row; r++)
    {
        arr[i][r] = new int[col];
    }
}
for (int i = 0; i < lists; i++)
{
   
    for (int r = 0; r < row; r++)
    {
        for (int z = 0; z < col; z++)
        {
            arr[i][r][z] = rand() % 100;
        }


    }
}
for (int i = 0; i < lists; i++)
{

    for (int r = 0; r < row; r++)
    {
        delete[] arr[i][r];

        
    }
    
    delete[] arr[i];
}
delete[] arr;
arr = nullptr;

【问题讨论】:

  • newed 的任何内容都应为 deleted。
  • “我正在努力避免内存泄漏”,因此请使用智能指针和/或容器。避免原始的拥有指针。
  • 不,您不需要arr = nullptr; 以避免内存泄漏。将其设置为 nullptr 的唯一原因是您稍后出于某种原因检查它 (if(arr) ...)。
  • 这不是必要的,如果你不为空指针不会有任何内存泄漏,但它会使其处于“悬空”状态。如果你不再使用它,那很好。如果有可能再次使用,最好设置为nullptr
  • 不要成为three star programmer

标签: c++ arrays multidimensional-array stl


【解决方案1】:

在您的情况下不会发生内存泄漏,但对于良好实践,您需要在删除该指针后将指针设为空,否则如果您稍后取消引用同一个变量,您的程序将出现未定义的行为

可能会出现“未处理的异常错误”。

if(arr) 

这种情况也无济于事。 所以在访问指针之前使用每个指针的空检查

【讨论】:

  • "否则,如果您访问相同的变量..." - 应该是:“否则,如果您稍后取消引用相同的变量,您的程序将具有未定义的行为”。
  • 无论您是否设置arr=nullptr,您都会有未定义的行为。设置arr=nullptr 只会让这种非法访问更容易调试。
  • “好的做法,你需要在删除指针后将指针清空”——我坐在栅栏的另一边;我个人认为这会导致草率的编码和仍然是错误的错误的掩盖。
【解决方案2】:

使用SmartPointers 来避免内存泄漏问题。

不,您不需要将指针变量设置为“NULL”,程序将毫无问题地运行。

将其设置为 null 可以作为额外的安全措施,以防止错误地使用该变量。

-----------

运算符 new 保留空间,以便任何新的内存分配或编译器内部操作不会占用那些分配的内存位置。

操作员删除只是取消标记这些保留。引用变量仍然具有内存位置的地址,您可以访问它,但现在,编译器可以随时更改它。

删除操作前后指针变量的内容。

    int *a;
    cout<<"before memory allocation a= "<<a<<endl;
    a= new int[10];
    a[0]= 1; a[7]=2;
    cout<<"After memory allocation but Before Delete"<<endl;
    cout<<"a="<<a<<"\ta[0]="<<a[0]<<"\ta[7]="<<a[7]<<"\ta[22]="<<a[22]<<endl;
    cout<<"sizeof(a)="<<sizeof(a)<<"\tsizeof(a[7])="<<sizeof(a[7])<<"\tsizeof(a[22])="<<sizeof(a[22])<<endl;
    delete[] a;
    cout<<"After Delete"<<endl;
    cout<<"a="<<a<<"\ta[0]="<<a[0]<<"\ta[7]="<<a[7]<<"\ta[22]="<<a[22]<<endl;
    cout<<"sizeof(a)="<<sizeof(a)<<"\tsizeof(a[7])="<<sizeof(a[7])<<"\tsizeof(a[22])="<<sizeof(a[22])<<endl;
    return 0; 

结果:

before memory allocation a= 0x40ed39
Before Delete
a=0x9a1550      a[0]=1  a[7]=2  a[22]=1316552972
sizeof(a)=8     sizeof(a[7])=4  sizeof(a[22])=4

After Delete
a=0x9a1550      a[0]=10099280   a[7]=2  a[22]=1316552972
sizeof(a)=8     sizeof(a[7])=4  sizeof(a[22])=4

【讨论】:

    【解决方案3】:

    这实际上只是一个代码卫生问题。我认为在删除后设置arr = nullptr 的主要好处是您可以在以后的任何时间安全地delete arr[] 而不必担心。如果您尝试引用已删除的数组,它还可以更容易地捕获错误。

    所以这不是强制性的,但这是我个人理所当然的事情。

    【讨论】:

      【解决方案4】:

      删除多维动态数组后是否需要清空指针

      这取决于。有时是,有时不是。

      当您需要检查是否仍有有效指针时,您必须将无效指针设置为 null,因为 null 指针是您可以测试的唯一无效指针。您的示例并未证明您需要这样做。

      delete 经常用在指针的生命周期即将结束的地方,在这种情况下,将其设置为 null 是完全多余的。

      附:不要像这样使用拥有裸指针。使用 RAII 容器,例如 std::vector 或至少使用智能指针。

      【讨论】:

        猜你喜欢
        • 2020-06-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-30
        • 1970-01-01
        • 2013-04-06
        • 1970-01-01
        相关资源
        最近更新 更多