【问题标题】:Should I use string or char[]?我应该使用字符串还是 char[]?
【发布时间】:2023-03-25 22:47:02
【问题描述】:

所以我想要一个带有这样一个结构数组的缓冲区:

EventItem
{
   tag; // some string or array of characters to describe the value;
   value; // some integer or something

}

该值可以是 int32 之类的任何值。我关心的是标签。如果我有一个这些对象的数组,并且我将标签设为字符串,那么如果用户将 EventItem 输入到这个具有长标签的缓冲区中会发生什么?这是否会导致缓冲区或其中的一部分被复制到内存中的其他位置来保存这个更大的 EventItem(因为这个长字符串而更大)?

使用数组而不是字符串,仅使用固定数量的字符来限制标签​​对我来说会更好吗?

显然我不知道我在说什么,但我不知道如何在不知道 EventItems 大小的情况下使用正确数量的连续空间创建缓冲区。

谁能为我解释一下这种情况会怎样?

提前非常感谢!

【问题讨论】:

  • 在不知道其他细节的情况下很难发表评论,例如是与C模块需要(POD)兼容所需的数据结构。
  • 感谢您的回答。你们很多人都说不要担心它,因为它会照顾好自己。这将是另一个循环缓冲区内的循环缓冲区。我将从 VME 设备每秒获取大约 30 MB 的数据,并且我想尽可能地减慢这个过程。我只是不知道复制和重新分配会在多大程度上发生。如果 String 将它的值存储在其他地方,那么我猜你们都是对的,没关系!谢谢

标签: c++ string memory char


【解决方案1】:

你想要的是std::string

不仅因为它是 c++ 而不是 c,还因为在 std::strings 上操作比在 char[] 上容易得多。

此外,结构的构建也可能更简单直接,避免复制char[]

struct EventItem{

   EventItem(const int_32 value,const std::string&tag):m_value(value),m_tag(tag){}

   int_32 m_value;
   std::string m_tag;
};

我关心的是标签。 如果我有这些对象的数组, 我把标签变成了一个字符串,什么 如果用户输入一个 将 EventItem 放入此缓冲区中,该缓冲区具有 长标签?这会导致缓冲区 或要复制到的部分 内存中的其他地方来保存这个 更大的 EventItem(更大是因为 这么长的字符串)?

不清楚(IMO),但我倾向于“不,不要担心”。可能发生的唯一方法是缓冲区跨越页面边界(假设此处为分页内存)。好吧,如果它发生了,它就会发生。虚拟内存的奇迹会照顾它。

显然我不知道具体是什么 我在说,但我不知道 如何使用 适量的连续空间 在不知道大小的情况下 EventItems 提前。

std::vector 解决这个问题。当然,可能总是出现连续空间不可用的情况。你为什么这么担心。你能向我们解释一下这会成为问题的情况吗?

【讨论】:

  • 应该使用 this.value 和 this.tag 访问 value 和 tag 变量(而不是像你那样:this->value 和 this->tag)。
  • 值参数请使用 const 引用。虽然不方便,但这应该是首先要学习的一些东西。
  • @Tom:你的代码不是惯用的。应该是这样的:pastebin.com/0PeqtvqT
【解决方案2】:

如果我有一个由这些对象组成的数组,并且我将标签设为字符串,那么如果用户将 EventItem 输入到这个具有长标签的缓冲区中会发生什么?这是否会导致缓冲区或其中的一部分被复制到内存中的其他位置来保存这个更大的 EventItem(因为这个长字符串而更大)?

如果您使用std::string,那么无论您对字符串成员做什么,EventItem 本身的大小都不会增加(或减少)。 std::string 通过将其存储在其他地方来管理其实际内容。它里面可能包含一个指向在别处分配的内存的指针(可能使用new)。如果它需要扩展以存储更多内容,它只需分配新内存、复制数据并释放旧内存。 std::string 对象本身始终保持相同的大小。

这几乎适用于 C++ 中的所有内容。 std::vector、std::list 等。基本上任何似乎以某种方式动态扩展以存储越来越多内容的对象实际上都是使用指针和new 将内容存储在其他地方。

另一方面,如果您将自己的指针存储到在 std::string 或 std::vector 等对象中管理的某些内容片段,则必须小心。当向这样的容器添加更多元素时,整个集合最终可能会被复制到其他地方,从而使您的指针无效。

因此,如果您可能有 std::vector,那么任何时候您向该向量添加另一个 EventItem 都可能将整个组移动到内存中的其他位置。但是当然,如​​果您只通过向量的方法(例如 at() 或 operator[])访问这些元素,那么您甚至不会注意到其中的区别。

【讨论】:

    【解决方案3】:

    这取决于缓冲区需要包含什么。通常数据缓冲区内不允许有真正的指针。这甚至排除了像std::string 这样简单的数据结构。如果这不是必需的,请重新考虑您是否真的需要平面数据缓冲区。

    固定分配字符串的数据缓冲区在 C++ 中没有位置。小型嵌入式系统,是的。通常此类应用程序不涉及“描述价值”。

    最有可能的是,您应该清理所有使用数组、缓冲区、char[] 和持久原始指针的应用程序,以支持vectorstring 和托管结构。

    【讨论】:

      【解决方案4】:

      两者都很糟糕。请改用QString

      【讨论】:

      • 你是不是建议每一个C++字符串问题的解决方法都是导入Qt库?
      猜你喜欢
      • 1970-01-01
      • 2010-10-21
      • 1970-01-01
      • 1970-01-01
      • 2019-01-29
      • 2011-01-05
      • 2011-02-08
      • 1970-01-01
      • 2018-09-25
      相关资源
      最近更新 更多