c++如何释放和删除指向对象的二维数组

标签 c++ arrays pointers

在 SO 问题 [How to allocate a 2D array of pointers in C++] [1] 中,接受的答案还记录了如何取消分配和删除所述数组的正确过程,即“小心删除分别包含指针、行数组和列数组,并且顺序正确。”所以,我已经在元胞自动机模拟程序中成功地使用了这个二维数组。但是,我不能正确地管理这个数组的内存。除了上面的引用之外,我没有看到关于如何执行此操作的 SO 答案。

我按如下方式分配二维数组:

Object*** matrix_0 = new Object**[rows];
    for (int i = 0; i < rows; i++) {
        matrix_0[i] = new Object*[cols];
    }

我徒劳的尝试(根据 Valgrind)正确取消分配上述数组如下:

for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
        matrix_0[i][j] = NULL;
    }
}
delete [] matrix_0;
matrix_0 = NULL;

很明显,我遗漏了引用文献 [1] 中建议的行和列部分。你能告诉我我错过了什么吗?提前致谢。

[1]:(2009 年 11 月 20 日)How to allocate a 2D array of pointers in C++

最佳答案

你有大量的删除工作要做:

for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
        delete matrix_0[i][j]; // delete stored pointer
    }
    delete[] matrix_0[i]; // delete sub array
}
delete [] matrix_0; //delete outer array
matrix_0 = NULL;

没有必要NULLmatrix_0 以外的任何内容因为它们在删除后就消失了。

这太可怕了,也没有必要。 Use a std::vector 并认真重新考虑指向包含对象的指针。

std::vector<std::vector<Object*>> matrix_0(rows, std::vector<Object*>(cols));

得到你想要的,将删除工作减少到

for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
        delete matrix_0[i][j]; // delete stored pointer
    }
}

但 SergeyA 建议存储 unique_ptr , std::vector<std::vector<std::unique_ptr<Object>>> matrix_0;将所需的删除减少到 0。

由于速度是 OP 的目标之一,因此还有一个改进:

std::vector<std::unique_ptr<Object>> matrix_0(rows * cols);

访问是

matrix_0[row * cols + col];

这用一些可见的数学来换取目前在幕后进行的不可见的数学和指针取消引用。重要的部分是 vector 现在存储为一个很好的连续内存块,增加了空间局部性并减少了缓存未命中的次数。它无法解决由指向 Objects 的指针导致的未命中问题。分散在整个内存中,但你不能总是赢。

关于 vector 的注释与阵列。一次vector已经建成,在这种情况下,它是一次性完成的:

std::vector<std::unique_ptr<Object>> matrix_0(rows * cols);

所有vector is 是一个指向 an 的指针,还有几个其他指针指向标记结束和最后使用的位置的位置。访问数据数组与访问使用 new 生成的动态数组没有区别.使用索引运算符 []编译为 data_pointer + index与使用 [] 完全相同在一个数组上。没有 Java 的 Vector 中的同步等。这只是简单的原始数学。

与动态数组相比,所有的预分配 vector成本是两个指针的内存,作为返回,您几乎没有遇到内存管理问题。

关于c++如何释放和删除指向对象的二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36138946/

相关文章:

c++ - ofstream 未将 "\r\n"转换为换行符

c++ - 获取字符串的最后一行

c# - 为什么数组实现 IList?

c - 如果 "argstr"是 C 中的二维数组,那么 argstr = argstr[0] 怎么办?为什么值(value)观不一样?

c++ - 如何使用 MPI 程序从命令行读取参数?

java - 使用 String#split() 分割表达式

python - 左旋转数组

有人能解释一下指针的指针是如何工作的吗?

c - `*a =` 和 `= *a` 有什么区别?

c++ - 如何将文件中的字符放入二维 vector 中?