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

2024-05-02

在SO问题[如何在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日)如何在 C++ 中分配二维指针数组 https://stackoverflow.com/questions/1768294/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;

没有必要NULL除了matrix_0因为删除后它们就消失了。

这是可怕且不必要的。Use a std::vector http://en.cppreference.com/w/cpp/container/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];

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

注释vector与数组。一旦vector已经建成,在本例中,这一切都在这里一次性完成:

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

all a vectoris 是一个指向 an 的指针,还有几个其他指针来标记结束和最后使用的位置的位置。访问数据数组与访问由以下命令创建的动态数组没有什么不同new。使用索引运算符[]编译为data_pointer + index与使用完全相同[]在一个数组上。没有像 Java 的 Vector 中那样进行同步或类似操作。这只是简单的原始数学。

与动态数组相比,所有预分配的vector花费你两个指针的内存,作为回报,你几乎不会遇到任何内存管理问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++ 如何释放和删除指向对象的指针的二维数组 的相关文章

随机推荐

  • WebBrowser 控件和 JavaScript 错误

    当我使用浏览器 ie9 访问该页面时 浏览器渲染正常 当我使用 WebBrowser 控件时 出现 JavaScript 错误 我知道我可以抑制脚本错误 但我希望它们正确运行 因为它们会影响页面的渲染和功能 我怎么解决这个问题 我可以将 I
  • 如何在C++控制台中删除已写入的字符

    我正在尝试编写一个 C 程序来读取密码 我编写了程序来计算 不是我写的字符 但我的问题是当我想删除字符时 因为它们是错误的 Example 我的固定密码是12345如果我输入1235该程序将显示 我必须删除最后一个字符 将其从字符串中删除很
  • 谷歌云sftp的权限

    我正在使用 wordpress 和 google cloud 并将其设置为 sftp 连接 文件夹的权限是755 文件的权限是644 即使我已经将Cloud API访问范围更改为 允许完全连接 当我尝试通过 WordPress 后端添加插件
  • 使用 git-svn 时模拟 subwcrev

    我使用 git svn 与包含一些 C 项目的现有 SVN 存储库进行交互 subwcrev exe 用作预构建事件来更新 C 标头 svnversion h 中的某些字符串 这些字符串被硬编译以形成生成的二进制文件的一些版本信息 由于 s
  • 如何在 R 中按字符变量的字母顺序对数据框进行排序?

    我想按 R 中字符变量的字母顺序对数据框进行排序 我尝试使用order 函数 但它将我的数据框转换为列表 有人知道吗 好吧 我这里没有问题 df lt data frame v 1 5 x sample LETTERS 1 5 5 df v
  • 我可以用 SASS \ Compass 计算和使用元素高度吗

    我在 RoR 项目中使用 sass 和 compass 我需要分配给top元素的 CSS 属性值 即元素高度除以 2 我可以用 SASS Compass 来做吗 你似乎已经得到了XY问题 https meta stackexchange c
  • 无法删除 windows 对象的事件侦听器

    我在尝试删除事件监听器时遇到了很多麻烦 我创建了一个非常依赖 JavaScript 的网站 当您在网站上导航时 它基本上是动态加载元素 而无需使用模板文字刷新页面 有时我必须加载内容并添加无限滚动 但也能够再次删除该事件 这是我用来处理滚动
  • MATLAB:生成给定三种颜色的颜色图

    我正在尝试在 MATLAB 中生成给定三种颜色 最高值 零值和最低值 的颜色图 我的思维过程是从最高端到中间循环 并将每个步骤存储到一个 3xN 第一列是 R 第二列是 G 第三列是 B 矩阵 所以我正在使用 fade from high
  • 谷歌地图动画符号(到达路径的目的地点后停止图标)

    我正在做一个学校项目 我正在使用 Google Map API API 很棒 但我需要一些代码方面的帮助 到达目的地后 我希望图标保留在那里 而不应该再次重复整个路径 function initMap var map new google
  • Java Paint 组件转换为位图

    我需要在位图中绘制组件及其所有子组件的内容 如果我想绘制整个组件 以下代码可以完美运行 public void printComponent Component c String format String filename throws
  • 使用 py2exe 在 .exe 中嵌入图标,在 Vista 中可见?

    我一直在尝试使用 py2exe 将图标 ico 嵌入到我的 编译 exe 中 Py2Exe 确实有一种嵌入图标的方法 windows script MyScript py icon resources 1 MyIcon ico 这就是我正在
  • 如何使用 jquery load 方法将文件的内容加载到变量中?

    如何使用 jQuery 将文件内容加载到变量而不是 DOM 中 load method 例如 logList load logFile function response 而不是将文件加载到 logListDOM 元素 我希望将其加载到变量
  • Gevent被flask阻塞甚至使用猴子补丁

    我正在使用flask gevent来构建我的服务器 但是名为 getall 的gevent被flask阻止 因此 getall 函数无法在这段代码中打印消息 猴子补丁正在使用中 import time import WSGICopyBody
  • 安装MySQLdb(对于python)作为非压缩的egg

    安装说明是 python setup py build sudo python setup py install or su first 这给了我一个 egg 文件 如何告诉安装程序将文件转储为普通的未压缩库 Thanks 好吧 我不想回答
  • WiX Burn:从注册表读取 LaunchTarget

    我是 WiX 的新手 我试图让我的 Bootstrapper 在完成后启动我安装的应用程序 为了实现这一点 我正在使用
  • 调试 SSR node.js 服务器端 VSCode

    我在尝试调试 SSR React 应用程序 服务器端 时花费了太多时间 我们正在从头开始构建一个应用程序 这是一个非常大的项目 因此调试代码非常重要 服务器的 webpack 配置如下 const path require path con
  • 检测活动 RDP 会话

    我需要在我的应用程序中实现死人开关 如果应用程序从 RDP 运行 我需要在它失去与远程客户端的连接时采取行动 我知道当我在 RDP 中运行时使用 GetSystemMetrics SystemMetric SM REMOTESESSION
  • 卸载屏幕外的 UIImageView 图像

    我正在 Ipad 上编写一个应用程序 在我的应用程序的某个时刻 我使用presentModalViewController 呈现一个ViewController 我的 ViewController 是一个 UISScrollView 它采用
  • 播放框架 Ebean BigDecimal 分数

    我正在使用带有 Ebean 和 H2 数据库的 Play 框架 问题是 BigDecimalDB 脚本的结果为 sum decimal 38 但我想要的是 sum decimal 38 2 我已经尝试像这样定义模型中的值 Digits in
  • c++ 如何释放和删除指向对象的指针的二维数组

    在SO问题 如何在C 中分配指针的二维数组 1 中 接受的答案还说明了如何取消分配和删除所述数组的正确过程 即 小心删除包含的指针 行数组和列数组全部分开且顺序正确 因此 我已经在元胞自动机模拟程序中成功地使用了这个二维阵列 但是 我无法使