这种向量删除方法有什么问题吗?

2024-01-09

我有一个有效的删除方法,如下:

void deleteUserByID(int id, std::vector<Person*>& userList) 
{

    for(int i = 0; i < userList.size(); i++) {

        if (userList.at(i)->getID() == id) {

            userList.erase(userList.begin() + i);
        }
    }
}

但是,我在上面之前尝试过以下操作,但不明白为什么它不起作用。

而不是使用userList.erase(userList.begin() + i);,我正在使用delete userList.at(i)

我对 C++ 有点陌生,并被指示使用“delete”关键字删除堆分配的内存。我觉得应该将其从 Vector 中删除,但这是错误的。

为什么不delete userList.at(i)工作?我很好奇。任何信息都会有帮助。


这里有两个不同的概念在起作用。首先,是对设备的维护std::vector你正在使用的。向量的工作是保存一系列元素,并且在很多方面它并不真正关心这些元素实际上是什么。从向量的角度来看,它的元素将一直存在,直到有东西明确出现并要求删除它们为止。致电给erase告诉向量“嘿,你知道那个位置的元素吗?请把它去掉。”因此,当您拨打电话时erase,你告诉向量去掉它的一个元素。

独立地,有存储在向量中的对象。你正在存储Person *s,它们是指向Person对象。这些对象(我假设)被分配了new,所以每个人本质上都认为“我会永远活着,或者至少直到有人过来打电话delete在我身上。”如果你deletePerson 对象之一,该对象将不再存在。然而,Person 对象完全不知道某个地方有一个指向人的向量。

为了让一切按照您想要的方式工作,您实际上需要结合使用两者erase and delete(有一个警告,我稍后会提到)。如果你只是erase来自向量的指针,然后从向量的角度来看,所有内容都被清理了(它不再保存指向相关 Person 对象的指针),但从 Person 的角度来看,Person 对象仍然非常活跃并且运行良好,因为你从未说过delete它。如果你只是delete指针,然后从人的角度来看,所有东西都被清理了(你已经告诉人,是时候去天空中的巨大游乐场了),但是从矢量的角度来看,没有添加或删除任何内容,所以你现在有一个悬空的向量中的指针。换句话说,第一个选项会导致内存泄漏 - 有一个 Person 对象从未被告知清理自身 - 第二个选项会导致悬空指针 - 有一个指针指向曾经是一个人的对象,但现在是一个人一堆可以按照程序的意愿回收的位。

使用您现在拥有的设置,处理此问题的“最佳”方法是使用组合方法。当您找到要删除的项目时,首先delete指针,then call erase。这确保了 Person 被清理并且向量中不再有悬空指针。

但正如一些评论者指出的那样,有更好的方法可以做到这一点。而不是存储Person *s 并使用原始指针来引用Person对象,使用std::shared_ptr输入并管理您的Person物体通过std::shared_ptr<Person>。与常规指针不同,常规指针只是说“是的,那边有一个东西”并且不会自行执行任何内存管理,std::shared_ptr类型实际上拥有它所指向的资源。如果你erase a std::shared_ptr从向量中,std::shared_ptr然后说“好吧,我刚刚被踢出了向量,如果我是指向向量的最后一个指针Person,我去,delete为你服务。”这意味着你不需要自己进行任何内存管理来清理事情。

总之:

  • 只是打电话erase从向量中删除一个元素,但留下一个 Person 在堆中漂流,想知道为什么没有人再喜欢它了。
  • 只是打电话delete将 Person 对象设置为自由,但会在向量中留下一个指向它的幽灵指针,这是一个主要危险。
  • 呼叫两者delete and erase按正确的顺序可以解决此问题,但不是理想的解决方案。
  • Using std::shared_ptr而不是原始指针可能是最好的选择,因为它确保了所有正确的delete自动发生。

希望这可以帮助!


还有一个快速附录 - 您确定您的代码正确访问了向量的所有元素吗?例如,如果您erase索引 0 处的项,向量的所有其他元素将后移一位。但随后你的实施就会增加i到 1,此时您已跳过刚刚移回第一个位置的项目。

我让你想想如何解决这个问题。另一个答案提供了使用的好建议remove_if,这是一个很好的解决方案,但如果为了您自己的启发,您想推出自己的版本,您可能需要考虑如何解决上述问题。

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

这种向量删除方法有什么问题吗? 的相关文章

  • 如何在C++中生成非常大的随机数

    我想使用 C 生成 0 2 64 范围内的非常大的随机数 我已经使用了 rand 函数 但它没有生成非常大的数字 有人可以帮忙吗 使用c 11 使用标准c 11的随机库 http en cppreference com w cpp nume
  • 如何将这段 javascript 代码重写为 C++11?

    这是我在 Javascript Definitive Guide 中看到的 javascript 闭包代码 我想把它写成C 11 var uniqueID1 function var id 0 return function return
  • strtok() 使用安全吗[重复]

    这个问题在这里已经有答案了 我读到了很多负面的东西strtok 有人说它已经过时 有人说它不是线程安全的 等等 那么真相是什么 我可以使用吗strtok 它是线程安全的吗 Note 我正在使用 Visual C 您可以使用它 它是标准库的一
  • C# 异步任务比同步慢

    你知道为什么同步斐波那契方法比异步 等待更快并且比异步任务更快吗 我在每个项目方法上都使用了异步 所以主要是这是一个非常糟糕的方法 Code static int FibonacciSync int number if number 0 r
  • 信号与信号2

    我的应用程序可能会受益于使用 boost 的信号库之一而不是本土解决方案 该应用程序是多线程的 但执行信号处理的部分是单线程的 如果多线程不是问题 是否有任何理由更喜欢 Boost Signals2 而不是 Boost Signal Boo
  • Winform DatagridView 数字列排序

    我只使用一个简单的 DataGridView 来保存一堆数据 有趣的是 我在特定列中有小数 但是当按小数列排序时 它的排序是错误的 例如 起始顺序可能是 0 56 3 45 500 89 20078 90 1 56 100 29 2 39
  • 我可以将 char 或 DateTime 设置为 null 吗?

    我可以将 null 设置为char数据类型 并且DateTime在 C 中 多谢你们 这是不可能的 它是一个值类型 使用 char myChar null DateTime myDate null 这相当于 Nullable
  • C++ 指针和对象实例化

    这有效 MyObject o o new MyObject 而这并不 MyObject o new MyObject Why 关键词new 返回一个指针 http msdn microsoft com en us library kewsb
  • 从内存流播放视频文件

    只是好奇看看这是否可能 我有一个 Windows 应用程序 它从我的电脑上的 avi 文件读取所有字节 然后将其存储在 byte 中 现在我的内存中有 avi 文件 我想直接从内存将其加载到某种视频播放器控件中 我尝试过使用 wmplaye
  • 在 .NET Core 中从 HttpResponseMessage 转换为 IActionResult

    我正在将之前在 NET Framework 中编写的一些代码移植到 NET Core 我有这样的事情 HttpResponseMessage result await client SendAync request if result St
  • std::make_pair 与浮点数组(float2,无符号整数)

    我有一个用 float2 unsigned int 对模板化的向量 例如 std vector
  • 检查两个函数或成员函数指针的签名是否相等

    我编写了一些代码来检查自由函数的签名是否等于成员函数的签名等 它比较提取的返回类型和函数参数 include
  • 使用 cmake 将两种解决方案合二为一

    我有两个单独的 Visual Studio 2013 解决方案 我想将它们迁移到一个解决方案中 因为第一个解决方案 使用 Qt 充当第二个解决方案的 GUI 最后 我希望有一个结构如下的单一解决方案 Solution All Build P
  • 如果仅使用第一个元素,是否必须为整个结构分配内存?

    我有一个结构 其中第一个元素被测试 并且根据其值 结构的其余部分将被读取或不会被读取 在第一个元素的值指示结构的其余部分不会被读取的情况下 我是否必须为整个结构或仅第一个元素分配足够的内存 struct element int x int
  • 'iter' 的名称查找已更改为新的 ISO 'for' 范围

    我正在尝试编译下面的两个文件 但从编译器收到错误消息 gcc 4 3 3 Linux 错误位于带有以下符号的行 LINE WITH ERROR 我做错了什么 我该怎么改变 路易斯 g c b h b cpp b cpp In functio
  • 为什么 C++ 标准没有将 sizeof(bool) 定义为 1?

    Size of char signed char and unsigned char由 C 标准本身定义为 1 个字节 我想知道为什么它没有定义sizeof bool also C 03 标准 5 3 3 1 说 sizeof char s
  • Unity - 在生成时获取随机颜色

    我有一个小问题 我想在我的场景中生成四边形 它们都应该有红色或绿色作为材质 但 Random Range 函数只能是 int 我该如何解决它 void SpawningSquadsRnd rndColor 0 Color red rndCo
  • 检查一个数是否是完全平方数?

    我认为以下代码存在精度问题 bool isPerfectSquare long long n long long squareRootN long long sqrt n 0 5 return squareRootN squareRootN
  • 在 LP2844Z(Zebra 打印机)上的收据中包含 PNG [重复]

    这个问题在这里已经有答案了 我正在致力于创建一个基于 HTML5 画布的签名 绘图框 目前我们在服务器上将画布保存为PNG 但可以轻松地将base64字符串保存在数据库中 现在的问题是我们如何在打印的收据上添加签名 目前我们使用 GF 字段
  • 创建进程默认浏览器

    我目前正在使用 ShellExecute 打开 在用户浏览器中打开 URL 但在 Win7 和 Vista 中遇到了一些麻烦 因为该程序作为服务运行提升 我想获取线程 id 因此 ShellExecute 无法获取线程 id 因此我开始使用

随机推荐

  • 将 PST 格式的日期和时间转换为 UTC 格式

    我有一个变量 str 字符串类型 其值为 28 Nov 2013 09 15 AM 如何将其转换为 UTC 格式 str 变量中的上述时间采用 PST 因此 UTC 应该是 8超过这个时间 我正在使用 flex 2 下面发现以下代码不起作用
  • 居中浮动 DIV

    我正在尝试将 3 个浮动 DIV 居中 如果我给父级 DIV 就可以了显示 表格 和子 DIV显示 单元格 它将像一张桌子一样工作 还有别的办法吗
  • AttributeError:“模块”对象没有属性“utcnow”

    当我输入简单的代码时 import datetime datetime utcnow 我收到错误消息 Traceback most recent call last File
  • webpack 构建后运行命令

    我想运行 webpack watch模式 并在每次构建后运行 shell 命令 将一个文件夹同步到另一个文件夹 I found 这个插件 https www npmjs com package on build webpack每次构建后都会
  • 防止休眠 StaleObjectStateException 发生

    我对 Spring 控制器方法有疑问 它实际上对同一实体进行了两次更新 这导致陈旧对象状态异常 问题是 当我检索 Member 实例时 我认为它会以某种方式导致更新 请参阅 UPDATE ONE 的广告实例 这实际上是不需要的 以及当我更新
  • 替换 SQL 中字符串中第一次出现的子字符串

    我必须从 temp 表中获取数据 其中包含 或 ccc 或 bbb 或 aaa 之类的内容 我想将第一次出现的内容替换为空间以获得类似 ccc 或 bbb 或 aaa 之类的内容 我正在尝试一些东西并替换 但它们似乎没有给我带来想要的结果
  • Django 中“max_length”的最大大小是多少?

    这是我的模型 class Position models Model map models ForeignKey Map primary key True members models CharField max length 200 La
  • urllib2 和 json

    谁能指出一个教程 向我展示如何使用 urllib2 执行 POST 请求 数据为 JSON 格式 仅当服务器不费心检查内容类型标头时 梅萨的答案才有效 如果您希望它真正起作用 您需要指定一个内容类型标头 这是经过修改以包含内容类型标头的 M
  • Google Tasks API BatchRequest 触发“批量请求中的重复请求 ID”

    从 9 月 13 日开始 Google Tasks BatchRequest 更新工作流程将在多年来保持稳定的应用程序中触发 400 错误返回 批量请求中的重复请求 ID 我在请求中找不到任何指示重复请求 ID 的内容 有人知道怎么回事吗
  • 更改表格的 CCK 标题

    默认情况下 CCK 表单创建具有表单标题 Create Your Content Type Name Here 我想把我的改成 Register for Such and Such 有人建议我可以使用字符串覆盖 但我找不到要替换的字符串 我
  • 带有响应图像的 2 列 CSS 响应式布局

    我已经浏览了尽可能多的关于这个主题的帖子 但没有一个能解决这个难题 是否可以让左列包含文本 右列包含图像 调整大小时 图像会流入单个列 并带有自动调整大小的图像 在 img 上使用 100 的最大宽度将使图像响应并自动调整大小 但是 自动调
  • 如何使无窗口/命令行应用程序返回但继续在后台执行?

    我正在 Net 中编写一个命令行应用程序 该应用程序本身相当简单 但它必须同步连接到 Web 服务 而 Web 服务又必须连接到 Oracle 数据库 并且those作品喜欢慢慢来 是否有一种简单的方法 无需将我的应用程序 exe 一分为二
  • PHP、mysql编码UTF-8

    我正在进行基本的 PHP 和 MySQL 搜索 我国通常使用的字符编码是 utf 8 或 euc kr 当我输入英文关键字时 结果显示良好 但是 输入韩语关键字 结果不会显示在屏幕上 未显示结果计数 我正在 Eclipse PDT 上编码
  • Python 中无法连接字符串和整数的原因[重复]

    这个问题在这里已经有答案了 大量文献记载了这一点str需要先将整数转换为字符串 然后才能连接它们 I am str n years old Python不允许一定有根本原因 I am n years old 我想知道原因是什么 在我的项目中
  • 函数到函数指针的“衰减”

    我们知道一个参数看起来像void 将被重写为void 这类似于数组到指针的衰减 其中int 变成int 在很多情况下 使用数组会将其衰减为指针 除了参数之外 是否存在函数 衰减 的情况 C 标准规定 8 3 5 5 确定各个参数的类型后 任
  • 将 x 轴标签放置在句点刻度之间

    我想将 x 轴标签放置在刻度之间 For example by default R produces a graph that looks like this Note I added axis 1 c 2001 2002 2003 200
  • 带倒计时器的 QMessageBox

    我想知道向倒计时器添加倒计时器的最佳方法是什么QMessageBox 例如 当显示消息框时 倒计时器会启动 例如 5 秒 如果用户没有响应消息框 消息框将选择默认选项 像这样的事情怎么样 include
  • C++ - 从 std::string 类派生类以添加额外的功能?

    首先 我知道std string类具有我可能需要的所有功能 这只是为了测试目的 看看我将来能做什么 反正 说我有这个 class MyString public std string 例如 我将如何使用 MyString varName w
  • 用 C++ 编写 MIDI 文件

    您好 我在寻找有关此问题的正确信息时遇到一些问题 如果有人能指出正确的方向 我会很高兴 如何编码 midi 文件 例如我怎样才能编写一个播放随机音调 1 秒的片段 基本上我需要完成的是将不同的 midi 旋律表示为某种向量 我怎样才能做到这
  • 这种向量删除方法有什么问题吗?

    我有一个有效的删除方法 如下 void deleteUserByID int id std vector