删除多维动态数组后是否有必要使指针为空

问题描述

我正在尝试避免内存不足,并且需要了解是否需要将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;

解决方法

删除多维动态数组后是否有必要使指针为空

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

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

delete通常用于指针的寿命即将结束的地方,在这种情况下,将其设置为null完全多余。

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

,

在这种情况下,不会发生内存泄漏,但是对于优良作法,您需要在删除该指针之后将指针清空,否则,如果您访问相同的变量,则稍后

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

Eigen::MatrixXd A; // reading from a file,see below for a simple sample
Eigen::MatrixXd b; // reading from a file

Eigen::VectorXd x_svd = A.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(b);

//convert to sparse matrix
Eigen::SparseMatrix<double> As = A.sparseView(0.1,1e-5);

tau = 1e-3; // check coefficients are close or not

// SparseQR
{
Eigen::SparseQR<Eigen::SparseMatrix<double>,Eigen::COLAMDOrdering<int>> solver;
//solver.setPivotThreshold(1e-10);
solver.compute(As);
if (solver.info() != Eigen::Success)
    std::cout << "SparseQR::Decomposition Failed" << std::endl; 
Eigen::VectorXd xs = solver.solve(b);

if (solver.info() != Eigen::Success)
    std::cout << "SparseQR::Solving Failed" << std::endl;
std::string str_equal = xs.isApprox(x_svd,tau) ? " Equal" : " UnEqual";
std::cout << "Results::" << str_equal << std::endl;
std::cout << "EstimatedError: " << (As * xs - b).norm() / b.norm() << std::endl;
}

// ConjugateGradient
{
Eigen::ConjugateGradient<Eigen::SparseMatrix<double> > solver(As.transpose() * As);
if (solver.info() != Eigen::Success)
    std::cout << "CG::Decomposition Failed" << std::endl;
Eigen::VectorXd xcg = solver.solve(As.transpose() * b);
if (solver.info() != Eigen::Success)
    std::cout << "CG::Solving Failed" << std::endl;

std::cout << "#Iterations: " << solver.iterations() << std::endl;
std::cout << "EstimatedError: " << solver.error() << std::endl;
std::string str_equal = corr.isApprox(para_coeff,tau) ? " Equal" : " UnEqual";
std::cout << "Results::" << str_equal << std::endl;
}

也无助于这种情况。 因此在访问指针之前对每个指针使用null检查

,

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

这不是强制性的,但这是我个人当然要做的事情。

,

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

否,您不需要将Pointer变量设置为“ NULL” ,程序将无问题运行。

将其设置为null可以起到额外的安全性,以防止错误使用该变量。

-----------------------

操作员新建保留空间,以便任何新的内存分配或用于内部操作的编译器都不会占用那些分配的内存位置。

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

删除操作之前和之后Pointer变量的内容。

    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