使用管理器和向量时出现内存错误

2024-02-07

我想创建一个包含多个对象的管理器,并且必须使用它才能实际创建对象。 这些对象将其信息保存在智能指针中。 这就是我的实现方式:

struct Object
{
    std::shared_ptr<int> number;
};

struct Manager
{
    std::vector<Object> objects;
    Object& createObject()
    {
        objects.emplace_back();
        return objects.back();
    }
};

int main()
{
    Manager manager;
    Object& object1 = manager.createObject();

    object1.number = std::make_shared<int>(10);

    for (Object& o : manager.objects)
    {
        std::cout << *o.number << std::endl;
    }
}

如果我执行此代码,我会得到预期的输出:10

但是一旦我尝试创建多个像这样的对象:

Manager manager;
Object& object1 = manager.createObject();
Object& object2 = manager.createObject();

object1.number = std::make_shared<int>(10);
object2.number = std::make_shared<int>(5);

for (Object& o : manager.objects)
{
    std::cout << *o.number << std::endl;
}

我在该函数的内存库中收到运行时错误:

void _Decref()
        {   // decrement use count
        if (_MT_DECR(_Uses) == 0)
            {   // destroy managed resource, decrement weak reference count
            _Destroy();
            _Decwref();
            }
        }

有人知道为什么会发生这种情况吗?


将类实例向量与这些类实例的指针或引用结合使用从来都不是一个好主意。就像 Bo Persson 已经正确回答的那样,由于 a 的动态性质,这些指针或引用往往会变得悬而未决。std::vector: 当一个std::vector随着增长,它经常将其项目复制到不同的内存位置,使已经存在的项目引用和指针无效(悬空)。

您可以通过存储指向类的指针而不是类本身来轻松避免这种情况。

struct Manager
{
    std::vector<std::unique_ptr<Object>> objects;
    Object& createObject()
    {
        objects.emplace_back(std::make_unique<Object>());
        return *objects.back().get();
    }
};

Now std::vector可能会移动unique_ptr随心所欲 - 智能指针内容(原始指针)以及引用永远不会改变(当然,除非您故意更改或删除它们)

下面是使用类实例向量时会发生的情况的说明。 灰色垂直条纹象征着内存——内存的真实结构和大小在这里被忽略。

第 1 步:您有一个向量(用方括号表示),其中包含一个类实例作为项目。矢量后面的内存被占用(现实有点不同,但是图像应该足够了)

第 2 步:创建对类实例的引用(或指针)。 (绿箭)

步骤 3:将第二个类实例添加到向量中。向量没有空间容纳其项目,因此必须将其内容移动到另一个内存位置。您的指针/参考已损坏! (红色箭头)

这是指针解决方案的说明:

第 1 步:你又得到了一个向量,但现在它是一个智能指针向量。它拥有一个指向(深绿色箭头)类实例的智能指针。

步骤 2:再次创建对类实例的引用(或指针)。 (绿箭)

步骤 3:将指向类实例的第二个指针添加到向量中。向量没有空间容纳其项目,因此必须将其内容移动到另一个内存位置。但这次只有智能指针被移动,而不是类实例本身!类实例 1 保留在其位置,智能指针 1 仍然指向类实例 1,您的引用保持不变,每个人都保持高兴:)

此外:除了是一种安全的解决方案之外,通常使用指针向量代替实例向量还具有性能优势。unique_ptr非常小,几乎总是比它们所指向的对象小得多。所以,当std::vector必须将其项目复制到不同的内存位置,如果这些只是小型智能指针,则要做的工作要少得多。 最重要的是,有一些类具有昂贵的复制构造函数(例如锁定!)。如果根本不复制类实例,所有这些都可以避免。

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

使用管理器和向量时出现内存错误 的相关文章

  • 从实体获取单列

    如何从查询中获取单个列而不是整个对象 我可以这样做来获取整个对象 但我想要的只是名称 IList
  • 如何使用 C# 以编程方式编辑 Power BI Desktop 文档参数或数据源?

    我有一个在 Power BI Desktop 中内置的报告模板 并保存为 pbix 或 pbit 文件 该模板使用DirectQuery SQL数据库作为数据源 而服务器地址和数据库名称被提取到参数中 还有一个参数包含一个ReportId
  • C# Outlook 从收件人获取 CompanyName 属性

    我目前正在使用 C 编写 Outlook 2010 AddIn 我想要的是从我从 AppointmentItem 中提取的 Recipient 对象中获取 CompanyName 属性 因此 有了 AppointmentItem 的收件人
  • 如何查明 .exe 是否正在 C++ 中运行?

    给定进程名称 例如 程序 exe C 标准库没有这样的支持 您需要一个操作系统 API 来执行此操作 如果这是 Windows 那么您将使用 CreateToolhelp32Snapshot 然后使用 Process32First 和 Pr
  • 从时间列表中查找最接近的时间

    所以 这是场景 我有一个带有创建时间的文件 我想从该文件的创建时间最接近或相等的时间列表中选择一个时间 完成此操作的最佳方法是什么 var closestTime listOfTimes OrderBy t gt Math Abs t fi
  • 如何调试在发布版本中优化的变量

    我用的是VS2010 我的调试版本工作正常 但我的发布版本不断崩溃 因此 在发布版本模式下 我右键单击该项目 选择 调试 然后选择 启动新实例 此时我看到我声明的一个数组 int ma 4 1 2 8 4 永远不会被初始化 关于可能发生的事
  • 虚拟并行端口模拟器

    在我的计算机网络课程中 我们应该通过使用本机寄存器 例如使用 outportb 等命令 来学习并行端口编程 我没有并行端口 因为我住在 2011 年 但想练习这些程序 我使用 dosbox 安装了旧的 Turboc 3 IDE 有没有一个程
  • Nhibernate:连接表并从其他表获取单列

    我有以下表格 create table Users Id uniqueidentifier primary key InfoId uniqueidentifier not null unique Password nvarchar 255
  • C 类型命名约定,_t 或 ALLCAPS

    我一直想知道是否有任何命名约定 例如何时对类型使用全部大写以及何时追加 t 什么时候不使用任何东西 我知道当时 K R 发布了各种有关如何使用 C 的文档 但我找不到任何相关内容 在 C 标准库类型中 t看起来漂亮占主导地位 time t
  • 检测 TextBox 中的 Tab 键按下

    I am trying to detect the Tab key press in a TextBox I know that the Tab key does not trigger the KeyDown KeyUp or the K
  • 为什么 std::function 不是有效的模板参数,而函数指针却是?

    我已经定义了名为的类模板CallBackAtInit其唯一目的是在初始化时调用函数 构造函数 该函数在模板参数中指定 问题是模板不接受std function作为参数 但它们接受函数指针 为什么 这是我的代码 include
  • 如何增加ofstream的缓冲区大小

    我想增加 C 程序的缓冲区大小 以便它不会过于频繁地写入 默认缓冲区是 8192 字节 我尝试使用 pubsetbuf 将其增加到 200K 原始代码 ofstream fq fastq1 cstr ios out fastq1 is a
  • 从点云检测平面集

    我有一组点云 我想测试3D房间中是否有角落 所以我想讨论一下我的方法 以及在速度方面是否有更好的方法 因为我想在手机上测试它 我将尝试使用霍夫变换来检测线 然后我将尝试查看是否有三条线相交 并且它们也形成了两个相交的平面 如果点云数据来自深
  • C 与 C++ 中的 JNI 调用不同?

    所以我有以下使用 Java 本机接口的 C 代码 但是我想将其转换为 C 但不知道如何转换 include
  • 在 Qt 中播放通知(频率 x)声音 - 最简单的方法?

    Qt 5 1 或更高版本 我需要播放频率为 x 的通知声音 n 毫秒 如果我能像这样组合音调那就太好了 1000Hz 持续 2 秒 然后 3000Hz 持续 1 秒 最简单的方法是使用文件 WAV MP3 例如如此处所述 如何用Qt播放声音
  • 时间:2019-03-17 标签:c#TimerStopConfusion

    我想通过单击按钮时更改文本颜色来将文本框文本设置为 闪烁 我可以让文本按照我想要的方式闪烁 但我希望它在闪烁几次后停止 我不知道如何在计时器触发几次后让它停止 这是我的代码 public Form1 InitializeComponent
  • 与 Entity Framework Core 2.0 的一对零关系

    我正在使用 C 和 NET Framework 4 7 将 Entity Framework 6 1 3 Code First 库迁移到 Entity Framework Core 我一直在用 Google 搜索 Entity Framew
  • 当 Verb="runas" 时设置 ProcessStartInfo.EnvironmentVariables

    我正在开发一个 C 应用程序 我需要创建变量并将其传递给新进程 我正在使用ProcessStartInfo EnvironmentVariables 新进程必须提升运行 因此我使用 Verb runas var startInfo new
  • 解释这段代码的工作原理;子进程如何返回值以及在哪里返回值?

    我不明白子进程如何返回该值以及返回给谁 输出为 6 7 问题来源 http www cs utexas edu mwalfish classes s11 cs372h hw sol1 html http www cs utexas edu
  • 如何知道 HTTP 请求标头值是否存在

    我确信这很简单 但是却让我感到厌烦 我在 Web 应用程序中使用了一个组件 它在 Web 请求期间通过添加标头 XYZComponent true 来标识自身 我遇到的问题是 如何在视图中检查此组件 以下内容不起作用 if Request

随机推荐

  • 如何将 Azure 管道变量传递到 AzureResourceManagerTemplateDeployment@3 任务使用的 ARM 模板?

    我尝试在每天晚上安排的 Azure 管道中执行以下 2 个步骤 将自签名证书放入密钥库 通过 ARM 模板部署 Service Fabric 集群 并使用证书指纹和秘密 ID 作为参数 在密钥库中创建证书的第一步对我来说效果很好 impor
  • 捕获程序的每个异常?

    我有一个在全球范围内运行良好的 WPF 应用程序 但有时 客户告诉我他遇到了一些崩溃 但除了他做了什么 我对发生的事情一无所知 有没有办法放置全局 try catch Exception LOGEXCEPTION throw 某处接收由 G
  • 巨大的性能差异:调试与发布

    我有一个简单的算法 可以将拜耳图像通道 BGGR RGGB GBRG GRBG 转换为RGB 去马赛克但没有邻居 在我的实现中 我有预设的偏移向量 可以帮助我将拜耳通道索引转换为其相应的 RGB 通道索引 唯一的问题是我在 MSVC11 的
  • 错误 LNK2019:无法解析的外部符号“toString(int)”

    环境 Windows XP Visual Studios 2010 语言 C 我遇到了以下链接错误 并且已经没有办法解决此问题 我有一个项目 CnD Device 它链接到我的团队控制的 2 个项目 Messages 和 Carbon 我尝
  • 在 Prolog 中打乱列表

    简单的问题 如何在 Prolog 中打乱列表 以便A1是洗牌后的列表吗 shuffle 1 1 1 2 3 4 A1 我尝试了在网上找到的一些谓词 但似乎都不起作用 还发现this http www cs uni potsdam de wv
  • 如何访问reduce中的第0个元素以计算数组中的重复次数

    在节点学校的突发奇想中 我正在尝试使用reduce计算字符串在数组中重复的次数 var fruits Apple Banana Apple Durian Durian Durian obj fruits reduce function pr
  • CloudKit 中私人存储的数据是否存储在用户的 iCloud 帐户中?

    我的应用程序涉及用户创建数据并将其保存到他们的私人数据库中 这些数据会占用他们的 iCloud 帐户空间 还是会成为我的 CloudKit 存储配额的一部分 谢谢 这包含在为 CloudKit 进行设计 https developer ap
  • VBA 未使用 Now() 返回正确的日期

    我有一个简单的代码 VBA 无法返回正确的日期 Sub Test Date Debug Print Format Month Now mmm Debug Print Month Now Debug Print Now End Sub 返回
  • 在图像上添加动态文本

    我正在为用户创建一个网站 他们可以在其中创建自定义徽标 为此 我需要一种工具来从用户将填写的文本框中添加动态文本 然后文本应出现在所选图像上 有没有什么办法 比如说Javascript 可以通过它来实现上述场景 对于我如何做到这一点的任何建
  • RecyclerView Grid - 定义每行的项目数

    我通常反对在没有代码的情况下发布问题 但我没有代码可以显示 我终于将我的项目从 listviews 和 gridviews 转换为 recyclerView 在一堂课中 我使用一个小型网格视图来放置从服务器拉取的项目 每行的最大项目数为 3
  • 尝试在 Rails 中调用我的服务时出现“未初始化常量”

    我正在使用 Rails 4 2 3 我在控制器中有这一行 service XACTEService new Event 2015 06 01 Zoo 有问题的类在 app services XACTEService rb 中定义 然而 在访
  • XmlSerializer 列表项元素名称

    我有课PersonList XmlRoot Persons PersonList List
  • Web 应用程序的传入请求是否有配额?

    我正在运行一个脚本 该脚本通过 URL 访问更改 Google 表格中的行 部署为 Web 应用程序 例如macroUrl sheet SheetName key KeyName value ValueName 这非常适合我的需要 但我不确
  • 与 TypeScript 混合模式?

    我读过这篇文章 https justinfagnani com 2015 12 21 real mixins with javascript classes https justinfagnani com 2015 12 21 real m
  • 增加 HTML 正文中的光标大小

    有没有什么方法可以在基于浏览器的应用程序中以编程方式增加光标的大小CSS or jQuery 我可以用 CSS 改变光标的类型 就像这样 body cursor crosshair 但我在 CSS 中没有看到增加光标大小的规定 没有关于光标
  • 你能让 ERB 在渲染时正确缩进吗?

    我有几个部分包含在 Rails 中application html erb file 但生成的 HTML 不会保留我的缩进 格式 我被告知第一行以与调用相同的缩进级别呈现 partial html erb 但部分中的所有后续行都会左对齐 这
  • jQuery 图片库非功能性淡入淡出效果

    这是一个简单的图像库脚本 用于淡入和淡出带有背景图像的 div 它很慢而且不能正常工作 看起来所有图像都一起出现和消失 没有任何动画 该画廊应该将每张图像淡出到下一张图像中 function gallery timerp window se
  • Imagemagick 将每个边缘切掉 30px(宽度和高度可变)

    我需要将每边切掉 30px 左上右下 我试过了crop并且 chop 30x30但这似乎只在一方面起作用 convert verbose density 150 trim pdfs test test pdf quality 80 chop
  • 源集 - Groovy -> Kotlin DSL

    sourceSets main java srcDirs src main kotlin src main java res srcDirs src main res layouts activity src main res layout
  • 使用管理器和向量时出现内存错误

    我想创建一个包含多个对象的管理器 并且必须使用它才能实际创建对象 这些对象将其信息保存在智能指针中 这就是我的实现方式 struct Object std shared ptr