【问题标题】:CString or char array which one is better in terms of memoryCString 或 char 数组哪一个在内存方面更好
【发布时间】:2013-03-24 17:16:52
【问题描述】:

我在某处读到 CString 的使用成本很高。你能用一个例子来校准它吗? CString 和 char 数组中也是,内存比较好。

【问题讨论】:

  • CString 来自 MFC 框架。 std::string 来自 c++ 标准。它们是用于管理内存中字符串的库类。除非您对内存非常挑剔,否则请使用这些类,因为它们提供了许多功能并且您不必担心越界检查等。std 字符串将为您提供代码可移植性。就内存而言,char 数组很好,但从长远来看,像 std 字符串这样的实用程序类有利于管理东西
  • 为什么不std::string
  • 你觉得哪个更容易编程?这应该是你主要关心的问题。计算机有很多内存,除非您正在编写一些非常特殊的程序,否则字符串使用的内存非常小,以至于几乎无关紧要。但是,由错误编写的字符串处理导致的错误代码非常常见且非常相关。

标签: c++ memory char cstring


【解决方案1】:

在几乎所有情况下,我都鼓励新手程序员使用 std::string 或 CString(*)。首先,他们会犯明显更少的错误。由于错误使用 C 数组,我见过很多缓冲区溢出、内存失效或内存泄漏。

那么,CString / std::string 还是原始字符数组哪个更有效?内存方面,一般来说,所有 CString 和 std::string 的大小都是一个整数。问题是这有关系吗?

那么在性能方面哪个更有效?好吧,这取决于你用它做什么以及你如何使用你的 C 数组。但是传递 CString 或 std::string arround 在计算上可能比 C 数组更有效。 C 数组的问题在于您无法确定谁拥有内存以及它是什么类型(堆/堆栈/文字)。防御性编程会产生更多的数组副本,你知道,只是为了确保你持有的内存在需要的整个持续时间内都是有效的。

如果 std::string 或 CString 按值传递,为什么它们比 C 数组更有效?这有点复杂,原因完全不同。对于 CString,这很简单,它实现为 COW(写入时复制)对象。因此,当您有 5 个源自一个 CString 的对象时,它不会使用更多的内存,直到您开始对一个对象进行更改。 std::string 有更严格的要求,因此不允许与其他 std::string 对象共享内存。但是如果你有一个更新的编译器,std::string 应该实现移动语义,因此从函数返回一个字符串只会导致指针的副本而不是重新分配。

很少有原始 C 数组是好的和实用的想法。

*) 如果您已经在针对 MFC 进行编程,为什么不直接使用 CString。

【讨论】:

    【解决方案2】:

    除了字符数组(或宽字符)之外,CString 还包含字符串大小、分配的缓冲区大小和引用计数器(另外用作锁定标志)。包含字符数组的缓冲区可能比它包含的字符串大得多——它可以减少耗时的分配调用的数量。另外,当 CString 设置为零大小时,它仍然包含两个 wchar 字符。

    自然地,当你将 CString 的大小与对应的 C 样式数组的大小进行比较时,数组会更小。然而,如果你想在 CString 允许的范围内尽可能广泛地操作你的字符串,你最终将定义你自己的字符串大小、缓冲区大小以及有时 refcounter 和/或保护标志的变量。实际上,您需要存储字符串大小以避免每次需要时都调用 strlen。如果您允许缓冲区大于字符串长度,则需要单独存储缓冲区大小,并避免在每次添加或减去字符串时调用 reallocs。依此类推——你用一些小尺寸的增加换取速度、安全性和功能的显着增加。

    所以,答案取决于你要对字符串做什么。假设您想要一个字符串来存储类的名称以进行日志记录——C 风格的字符串(常量和静态)就可以了。如果您需要一个字符串来操作它并将其广泛用于与 MFC 或 ATL 相关的类,请使用 CString 系列类型。如果您需要在应用程序的“引擎”部分中操作与其接口隔离的字符串,并且可能会转换到其他平台,请使用 std::string 或编写您自己的字符串类型以满足您的特定需求(这可以是当您编写“胶水”代码放置在接口和引擎之间时非常有用,否则 std::string 更可取)。

    【讨论】:

      【解决方案3】:

      CString 来自特定于 windows 的 MFC 框架。 std::string 来自 c++ 标准。它们是用于管理内存中字符串的库类。 std::string 将为您提供跨平台的代码可移植性。

      使用原始数组总是有利于内存,但是必须对字符串进行操作,使用原始数组会变得很困难,考虑越界检查,获取字符串长度,复制数组或更改大小,因为字符串可能会增长,删除数组等。对于所有这些问题,字符串实用程序类都是很好的包装器。字符串类会将实际字符串保留在堆中,并且您拥有字符串类本身的开销。但是,这将为您提供管理字符串内存的功能,无论如何您都必须手动编写。

      如果可以,最好使用std::string,如果不能,使用CString。

      【讨论】:

        猜你喜欢
        • 2021-02-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-09
        • 2012-06-04
        • 2019-08-16
        • 2018-11-05
        相关资源
        最近更新 更多