Rig*_*ody 0 c++ arrays pointers
在SO问题[如何在C++中分配2D指针数组] [1],接受的答案还记录了如何解除分配和删除所述数组的正确过程,即"小心删除包含的指针,行数组和列数组都是以正确的顺序分开的." 所以,我已经成功地在细胞自动机模拟程序中使用这个2D阵列.但是,我不能让这个数组的内存管理正确.除了上面的参考文献之外,我没有看到如何做到这一点的答案.
我按如下方式分配2D数组:
Object*** matrix_0 = new Object**[rows];
for (int i = 0; i < rows; i++) {
matrix_0[i] = new Object*[cols];
}
Run Code Online (Sandbox Code Playgroud)
我徒劳地尝试(根据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;
Run Code Online (Sandbox Code Playgroud)
很明显,我错过了行和列部分作为参考[1]建议.你能告诉我我错过了什么吗?提前致谢.
[1] :( 2009年11月20日)如何在C++中分配2D指针数组
你有一吨删除要做:
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;
Run Code Online (Sandbox Code Playgroud)
NULL除了matrix_0因为它们在删除后消失所以没有必要.
这太可怕了,没必要.使用astd::vector并认真重新考虑指向包含对象的指针.
std::vector<std::vector<Object*>> matrix_0(rows, std::vector<Object*>(cols));
Run Code Online (Sandbox Code Playgroud)
获取您想要的内容并将删除工作减少到
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
delete matrix_0[i][j]; // delete stored pointer
}
}
Run Code Online (Sandbox Code Playgroud)
但是存储的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);
Run Code Online (Sandbox Code Playgroud)
访问是
matrix_0[row * cols + col];
Run Code Online (Sandbox Code Playgroud)
对于当前在幕后进行的隐形数学和指针解引用,这会进行一些可见的数学运算.重要的部分是向量现在存储为一个很好的连续内存块,增加了空间局部性并减少了缓存未命中数.它无法帮助Objects分散在整个记忆中的指针所导致的失误,但你不能总是赢.
关于vectorvs数组的注释.一旦vector建成,在这种情况下,这一切都在这里完成:
std::vector<std::unique_ptr<Object>> matrix_0(rows * cols);
Run Code Online (Sandbox Code Playgroud)
all a vector是一个指向一个和几个其他指针的指针,用于标记end和所用最后一个位置的位置.对数据阵列的访问与访问使用的动态数组没有什么不同new.使用索引运算符可以[]编译data_pointer + index为与[]在数组上使用完全相同.Java的Vector中没有同步等.这只是简单的原始数学.
与动态数组相比,所有预先分配的vector成本都是两个指针值的内存,作为回报,你可以看到几乎没有内存管理问题.