C++:指针向量在push_back()之后失去引用

2023-11-27

在我的代码中,有一个 Node 对象的全局向量和一个 Node 指针的本地向量:

#include<cstdio>
#include<cstdlib>
#include<vector>

using namespace std;

class Node {
    int n;

public:
    Node(int i) : n(i);
    int getN() { return n; }
};

vector<Node> v;

int main() {
    vector<Node*> p;
    v.push_back(Node(1));
    p.push_back(&v[0]);
    printf("first node id : %d\n", (*p[0]).getN());

    return 0;
}

我将一个节点对象插入到全局向量中,并将该对象的指针插入到本地向量中。我上面的代码的输出是:

first node id : 1

但是,如果我将主要功能更改为:

int main()
{
    vector<Node*> p;
    v.push_back(Node(1));
    p.push_back(&v[0]);
    v.push_back(Node(2));
    p.push_back(&v[1]);
    printf("first node id : %d\n", (*p[0]).getN());

    return 0;
}

该代码打印一个垃圾值:

first node id : 32390176

我无法弄清楚问题所在。 是否vector数据结构在插入后更改每个对象的引用? 我怎样才能解决这个问题 ?


“向量在插入后会改变引用吗?”

可能是的。一个std::vector当您添加/时可能会重新分配其(堆)存储push_back()附加元素,使所有指针无效:

迭代器[读:指针]失效

(用于操作)push_back, emplace_back...如果向量改变了容量,所有这些[即。所有迭代器都无效]。如果没有的话,只有end().

“我怎样才能解决这个问题?”

如果向量的容量不会因插入而改变,则上述失效规则不适用 - 因为向量不会不必要地重新分配存储空间。因此,如果您在示例中将向量的容量预设为 2(例如,v.reserve(2)),指针将保持有效。如果您事先不知道大小,但可以延迟第二个向量(使用指针)的构造,则不必保留,只需在插入最后一个元素后即可获得大小。

上面的方法是非常不推荐, 然而。如果你要制作你的向量constant- 至少在您将构造和使用第二个向量的函数范围内 - 您将得到不重新分配的强有力保证。或者,如果您可以提前确定尺寸,则可以使用std::array,使用指向该容器存储的指针会更合适:

迭代器失效

通常,数组的迭代器在数组的整个生命周期中永远不会失效。

您也可以考虑存储indices到你的向量中(尽管向量也可能会缩小,使索引无效,或者你可能会在中间插入元素等)。

不管怎样,我怀疑你实际上可能不想做任何事情,也就是说,这似乎是一个不太好的解决方案,可以完全用不同的方法来处理。

PS - If the vector has a custom allocator then everything I've written might be irrelevant.

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

C++:指针向量在push_back()之后失去引用 的相关文章

  • 在 C# 中创建具有单独列的分隔文本

    我一直在尝试在 C 中创建一个制表符限制的文本文件 以便数据正确显示在单独的列中 Firstname Lastname Age John Smith 17 James Sawyer 31 我尝试过 t 字符 但我得到的只是 Firstnam
  • 如何读取扩展文件属性/文件元数据

    因此 我按照教程使用 ASP net core 将文件 上传 到本地路径 这是代码 public IActionResult About IList
  • C++ 中本地类中的静态成员变量?

    我知道我们不能宣布static本地类中的成员变量 但其原因尚不清楚 那么请问有人可以解释一下吗 另外 为什么我们不能访问非static函数内部定义的变量 内部已经定义了局部类 直接在局部类成员函数中 在下面给出的代码中 int main i
  • 互斥体实现可以互换(独立于线程实现)

    所有互斥体实现最终都会调用相同的基本系统 硬件调用吗 这意味着它们可以互换吗 具体来说 如果我使用 gnu parallel算法 使用openmp 并且我想让他们称之为线程安全的类我可以使用boost mutex用于锁定 或者我必须编写自己
  • XamlReader.Load 在后台线程中。是否可以?

    WPF 应用程序具有从单独的文件加载用户控件的操作 使用XamlReader Load method StreamReader mysr new StreamReader pathToFile DependencyObject rootOb
  • 读取文件特定行号的有效方法。 (奖励:Python 手册印刷错误)

    我有一个 100 GB 的文本文件 它是来自数据库的 BCP 转储 当我尝试导入它时BULK INSERT 我在第 219506324 行上收到一个神秘错误 在解决此问题之前 我想看看这一行 但可惜的是我最喜欢的方法 import line
  • 将 System.Windows.Input.KeyEventArgs 键转换为 char

    我需要将事件参数作为char 但是当我尝试转换 Key 枚举时 我得到的字母和符号与传入的字母和符号完全不同 如何正确地将密钥转换为字符 这是我尝试过的 ObserveKeyStroke this new ObervableKeyStrok
  • 存储来自其他程序的事件

    我想将其他应用程序的事件存储在我自己的应用程序中 事件示例 打开 最小化 Word 或打开文件时 这样的事可能吗 运行程序 http msdn microsoft com en us library ms813609 aspx and 打开
  • 在 C# 中循环遍历文件文件夹的最简单方法是什么?

    我尝试编写一个程序 使用包含相关文件路径的配置文件来导航本地文件系统 我的问题是 在 C 中执行文件 I O 这将是从桌面应用程序到服务器并返回 和文件系统导航时使用的最佳实践是什么 我知道如何谷歌 并且找到了几种解决方案 但我想知道各种功
  • 关于在 Windows 上使用 WiFi Direct Api?

    我目前正在开发一个应用程序 我需要在其中创建链接 阅读 无线网络连接 在桌面应用程序 在 Windows 10 上 和平板电脑 Android 但无关紧要 之间 工作流程 按钮 gt 如果需要提升权限 gt 创建类似托管网络的 WiFi 网
  • 如何将整数转换为 void 指针?

    在 C 中使用线程时 我面临警告 警告 从不同大小的整数转换为指针 代码如下 include
  • 将 log4net 与 Autofac 结合使用

    我正在尝试将 log4net 与 Autofac 一起使用 我粘贴了这段代码http autofac readthedocs org en latest examples log4net html http autofac readthed
  • 等待线程完成

    private void button1 Click object sender EventArgs e for int i 0 i lt 15 i Thread nova new Thread Method nova Start list
  • 有人可以提供一个使用 Amazon Web Services 的 itemsearch 的 C# 示例吗

    我正在尝试使用 Amazon Web Services 查询艺术家和标题信息并接收回专辑封面 使用 C 我找不到任何与此接近的示例 所有在线示例都已过时 并且不适用于 AWS 的较新版本 有一个开源项目CodePlex http www c
  • 如何对 Web Api 操作进行后调用?

    我创建了一个 Web API 操作 如下所示 HttpPost public void Load string siteName string providerName UserDetails userDetails implementat
  • 为什么在setsid()之前fork()

    Why fork before setsid 守护进程 基本上 如果我想将一个进程与其控制终端分离并使其成为进程组领导者 我使用setsid 之前没有分叉就这样做是行不通的 Why 首先 setsid 将使您的进程成为进程组的领导者 但它也
  • Server.MapPath - 给定的物理路径,预期的虚拟路径

    我正在使用这行代码 var files Directory GetFiles Server MapPath E ftproot sales 在文件夹中查找文件 但是我收到错误消息说 给定物理路径但虚拟路径 预期的 我对在 C 中使用 Sys
  • 有没有办法强制显示工具提示?

    我有一个验证字段的方法 如果无法验证 该字段将被清除并标记为红色 我还希望在框上方弹出一个工具提示 并向用户显示该值无效的消息 有没有办法做到这一点 并且可以控制工具提示显示的时间 我怎样才能让它自己弹出而不是鼠标悬停时弹出 If the
  • Linq-to-entities,在一个查询中获取结果+行数

    我已经看到了有关此事的多个问题 但它们已经有 2 年 或更长 的历史了 所以我想知道这方面是否有任何变化 基本思想是填充网格视图并创建自定义分页 所以 我还需要结果和行数 在 SQL 中 这将类似于 SELECT COUNT id Id N
  • 如何将 Roslyn 语义模型返回的类型符号名称与 Mono.Cecil 返回的类型符号名称相匹配?

    我有以下代码 var paramDeclType m semanticModel GetTypeInfo paramDecl Type Type Where paramDeclType ToString returns System Col

随机推荐

  • Java 8 DateTimeFormatter 在为零时会丢弃毫秒?

    这看起来很奇怪 Java 8 根据 millis 是否为零来格式化输出 如何强制 Java 8 1 8 0 20 始终输出毫秒 无论它们是否为零 public static void main String args TemporalAcc
  • Ruby BitTorrent 库 [关闭]

    Closed 这个问题需要细节或清晰度 目前不接受答案 我正在考虑用 ruby 编写定制的 torrent 客户端 我找到了以下库 正如马特下面指出的那样 它们相当古老 不过 我想听听我可能错过的任何图书馆 并且我很想听听社区对以下图书馆的
  • LD JSON 中的 Javascript

    我想知道是否可以在 ld json 脚本中执行一些 javascript 例如 window location hostname 不 application ld json 类型的脚本不会被执行 但是 你可以这样做
  • 如何从 Startup.cs 中写入日志?

    为了调试启动时失败的 NET Core应用程序 我想从startup cs文件中写入日志 我在文件中进行了日志记录设置 可以在startup cs 文件之外的应用程序的其余部分使用该设置 但不确定如何从startup cs 文件本身写入日志
  • React 原生 Base64 编码字符串

    我正在尝试使用来自的 base 64 库 https github com mathiasbynens base64 当我运行测试来验证代码时 我没有得到正确的结果 还有其他我可以使用的库吗 这是我运行的代码和得到的结果 import ut
  • 将旋转变换设置为 UIView 或其图层似乎不起作用?

    我试图在我的屏幕中拥有一个子视图 由一个视图控制器拥有 not当设备旋转时旋转 我的视图控制器允许按其应有的方式进行旋转 并且我尝试将 90 度旋转应用于一个 静止 视图以抵消整体旋转 问题是 无论如何 一切似乎都在旋转 而变换似乎没有做任
  • 将字节数组从 Oracle RAW 转换为 System.Guid?

    我的应用程序使用使用 DataReaders 在 ADO NET 中编写的自定义数据访问层与 Oracle 和 SQL Server 数据库进行交互 现在 我在 GUID 我们用作主键 和 Oracle RAW 数据类型之间的转换时遇到问题
  • firebase 部署时出现 NPM 错误 --only 函数的原因是什么

    我最近在尝试部署我的 firebase 功能时收到此错误 但是 自上次成功部署以来我没有更改任何依赖项 functions all necessary APIs are enabled i functions preparing funct
  • AutoFixture CompositeDataAttribute 不适用于 PropertyDataAttribute

    我正在尝试创建AutoPropertyDataAttribute基于CompositeDataAttribute从这个例子AutoFixture PropertyData 和异构参数 它适用于单组参数 但适用于更多组参数 这是代码 publ
  • 在 foreach 循环声明中使用 LINQ

    直接在 foreach 循环声明中声明 LINQ 是一种不好的做法吗 在表现或微妙的行为差异方面 例如 foreach string name in persons Select x gt x name Do something with
  • 获取 OSX 连接的 Wi-Fi 网络名称

    我需要获取 OSX 上当前连接的 Wi Fi SSID 的名称 我搞乱了 SystemConfiguration 框架 我觉得它就在那里 因为我能够获取网络位置的名称 但我并没有真正找到获取 Wi Fi SSID 的方法 将不胜感激任何帮助
  • rvm安装:ruby安装错误

    我想在我的 Linux Mint 12 上安装 ruby 我正在关注本教程 and this one 当我跑步时rvm install 1 9 3我看到这个错误 Installing Ruby from source to usr shar
  • 如何在 Swift 中解码 HTML 实体?

    我正在从网站提取 JSON 文件 收到的字符串之一是 The Weeknd 8216 King Of The Fall 8217 Video Premiere TheWeeknd SoPhi 我怎样才能转换类似的东西 8216变成正确的字符
  • 如何在 Java 中迭代字符串?

    public static Boolean cmprStr String s1 String s2 STUFF 我想迭代 s1 以确保 s1 中的每个字符都包含在 s2 中 public static Boolean cmprStr Str
  • django-allauth 将用户名设置为与电子邮件相同

    我有一个注册表单 只要求提供电子邮件和密码 当用户注册时 django allauth 通过从用户的电子邮件地址中去除 email 后缀来为该用户创建一个用户名 例如 如果用户使用 电子邮件受保护 他的用户名是 某些用户 并且如果另一个用户
  • ggplot 单个条上的透明度

    我目前正在尝试使用 ggplot 创建一个条形图 其中单个条形部分透明 我有以下代码 dt1 lt data table yr c 2010 2010 2011 2011 val c 1500 3000 2000 1100 x c a b
  • 指向数组第一个元素之前的指针

    在 C 语言中据说当指针引用同一个数组或超出该数组末尾的一个元素时 算术和比较就得到了明确的定义 那么数组第一个元素之前的一个呢 只要我不取消引用它就可以吗 Given int a 10 p p a 1 这样写是否合法 p 2 这样写是否合
  • 禁用菜单按钮?

    我有一个自定义菜单选项 如果单击屏幕上的按钮 我想禁止它弹出 我想过使用这段代码 但它不起作用 Override public boolean onPrepareOptionsMenu Menu menu if Schedule menu
  • 页面刷新再次触发该事件

    在asp net中 当我提交表单并刷新它时 数据再次重新提交 C 有没有办法在页面加载时捕获页面刷新事件 ASP NET 没有提供直接执行此操作的方法 另一方面 有一些技巧可以避免重复提交 提交后重定向 这是最糟糕的 即使它避免了重复提交
  • C++:指针向量在push_back()之后失去引用

    在我的代码中 有一个 Node 对象的全局向量和一个 Node 指针的本地向量 include