c ++中的sizeof显示字符串大小减一

Posted

技术标签:

【中文标题】c ++中的sizeof显示字符串大小减一【英文标题】:sizeof in c++ showing string size one less 【发布时间】:2012-08-25 06:05:33 【问题描述】:

在 C++ 中,我试图获取 string 的大小,比如“gibbs”;

当我使用sizeof 函数时,它返回的尺寸小于实际尺寸之一。

我有以下代码:

 string s = "gibbs";
 cout << sizeof(s) <<endl;

输出是:4。我猜应该是5。

如何解决此问题。我们可以在 sizeof 的返回值中添加 +1,但这会是完美的解决方案吗?

【问题讨论】:

string s = "elephantine"; cout &lt;&lt; sizeof(s) &lt;&lt; endl;打印的值是多少?机会是,那也是 4? 哪个奇怪的实现有这样一个 4 字节的字符串? 【参考方案1】:

sizeof(s) 给出对象s 的大小,而不是对象s 中存储的字符串的长度。

你需要这样写:

cout << s.size() << endl;

请注意,std::basic_string(以及扩展名std::string)有一个size() 成员函数。 std::basic_string 也有一个 length 成员函数,它返回与 size() 相同的值。所以你也可以这样写:

cout << s.length() << endl;

我个人更喜欢size()成员函数,因为标准库中的其他容器,如std::vectorstd::liststd::map等,有size()成员函数但没有length() .也就是说,size() 是标准库容器类模板的统一接口。我不需要专门为std::string(或任何其他容器类模板)记住它。成员函数std::string::length() 在这个意义上是一个偏差。

【讨论】:

@Hogan std::basic_string::size 很好,在我使用的最后一个 c++ 之后的两个版本。 我在尺寸/长度问题上很纠结。这可能来自我的 C 背景,其中 length(strlen) 是现在使用的字符数,而 size(sizeof) 是最大长度(大约)。在许多 OO 集合类中,这些称为长度和容量。 @paxdiablo:在 C++ 标准容器中,size 始终是当前存储在容器中的项目数,而capacity 是当前分配的大小。当然,C++标准容器也可以称为“OO集合类”。【参考方案2】:

您的示例中的sizeof(s) 返回std::string 的大小,与其成员指向的内容无关。

如何解决此问题。我们可以在 sizeof 的返回值中始终添加 +1,但这会是完美的解决方案吗?

不,这不会解决任何问题,因为该值是恒定的,并且sizeof 没有提供您期望的值。

如果您想知道字符串的字符序列所需的字符数,可以使用s.length()s.size() -- 将该值加 1 以了解终止字符串所需的大小。

还要注意sizeof 的值不会在库和平台之间保持一致。 std::string 的实现可能会有很大差异。特别是,您可能会看到指针大小的差异,并且您可能会看到小的字符串优化。

【讨论】:

...恰好是4,可能是因为它仅包含指向其他一些数据的指针,并且地址在主机环境中是 32 位的。 @veer:basic_string 不太可能使用 pimpl 成语,因为它是一个类模板;因此,其成员的实现必须在所有使用 basic_string 的翻译单元中都可用(这有点违背了 pimpl 习语的目的)。【参考方案3】:

因为这是系统上字符串类型的大小,而不是基础数据的大小。例如:

#include <iostream>

int main (void) 
    std::string s1 = "gibbs";
    std::string s2 = "a much longer string";
    std::cout << sizeof(s1) << '\n';
    std::cout << sizeof(s2) << '\n';

    std::cout << s1.length() << '\n';
    std::cout << s2.length() << '\n';

    return 0;

产生:

4
4
5
20

换句话说,您应该使用std::string::length() 来获取字符串的长度。

【讨论】:

在他的系统中,std::string 恰好是指针的大小——这很可能是 C++11 中禁止的 COW 实现。大多数现代实现都比指针大得多。 @BillyONeal 请参阅pimpl idiom 上的 c2wiki 文章。 @veer:basic_string 不太可能使用 pimpl 成语,因为它是一个类模板;因此,其成员的实现必须在所有使用 basic_string 的翻译单元中可用(这有点违背了 pimpl 习语的目的)。【参考方案4】:

sizeof 返回对象类型的大小,std::string,在您的系统上恰好是 4。这可能是因为您正在处理的std::string 的实现使用pimpl idiom - 即它仅包含一个指向您正在寻找的真实 实现的指针for,并且指针发生在您的主机环境中是 32 位的。不过,您更有可能使用的是 copy-on-write implementation 或 std::string,它不再符合 C++11 标准的规范。

std::string 被定义为std::basic_string 模板类的特化,特别是std::basic_string&lt;char&gt;;您应该在std::basic_string 上查看文档。看看std::basic_string::sizestd::basic_string::length

std::string s = "***";
std::assert(s.size() == 13);

【讨论】:

正如我在其他地方所说,pimpl 成语在这里不太可能。 OP 更有可能使用的是 basic_string 的实现,它执行写时复制,这在 C++11 中被禁止。现代实现通常至少是 3x sizeof(void*),用于存储开始、结束和容量指针。对小字符串进行优化的实现(例如 dinkumware)更大。 @BillyONEal 啊,谢谢,有道理。我记得读过关于std::move 谢谢各位朋友,我是C++菜鸟,非常感谢你们的支持。

以上是关于c ++中的sizeof显示字符串大小减一的主要内容,如果未能解决你的问题,请参考以下文章

在自动调整大小的标签中的不同行上显示 Swift 字符串数组

grepsedawk基础

linux文件目录相关命令

c 语言是不是需要头文件和库函数

linux-grep

C语言字符串打印出现特殊字符是怎么回事?请问如何解决这个问题?