【问题标题】:Why does Sizeof operator on a std::string yield unexpected result? [duplicate]为什么 std::string 上的 Sizeof 运算符会产生意外结果? [复制]
【发布时间】:2017-07-05 08:09:43
【问题描述】:

在以下代码中:

#include <iostream>
#include <string>
using namespace std;

int main() {
    char buff[100];
    _snprintf(buff, sizeof(buff), "%s %d", "Name",2); //snprintf incase of ideone
    string buffAsStdStr = buff;
    cout<<buffAsStdStr<<endl;
    cout<<"len: "<<buffAsStdStr.length()<<endl;
    cout<<sizeof(buffAsStdStr)<<endl;

    return 0;
}

buffAsStdStr 中字符串的长度为 6,但我在 Visual Studio 2012 中运行时 sizeof 显示的值为 28,在 ideone 中为 32。 预期大小为 7,包括尾随 NULL 字符。

sizeof 运算符出现这种意外结果的原因是什么? 为什么结果会在 Visual Studio 和 ideone 之间发生变化?

【问题讨论】:

  • 原因是你的预期错了:)
  • 这个问题确实有道理,尤其是对于刚开始学习 C++ 的人。
  • @Mr.C64 是的,我是初学者。现在明白了,一清二楚。谢谢大家!

标签: c++ string sizeof


【解决方案1】:

std::string 实例的sizeof 仅返回std::string 的“内部表示”的大小(以字节为单位),即您可以将其视为每个@ 的sizeofs 的总和987654326@的数据成员(也可能涉及到填充)。

例如,在 VS2015 的 32 位调试版本中,sizeof(std::string) 返回 28;在 64 位调试版本中,我得到 40;在 32 位版本中,我得到 24,而在 64 位版本中,我得到 32。

这是因为 std::stringinternal 表示会随着不同的构建选项而改变:例如调试构建通常包含额外的机制来帮助发现错误,这会增加表示的大小;此外,在 64 位构建中,指针更大,因此相对于 32 位构建,大小再次增加,等等。

因此,在 std::string 实例上调用的从 sizeof 获得的数字通常与构成字符串文本的 chars 的数量不同。要获取此号码,您必须致电std::string::size or std::string::length

【讨论】:

  • 有趣。 Visual Studio 中的小字符串缓冲区显然是 16 个字节。我有点惊讶他们没有在 32 位构建中将其设为 20,因此大小是 8 的倍数。也许他们不再关心 32 位构建。
  • @MartinBonner:在 VS2015 中,sizeof(std::string) 在 32 位 release 版本中为 24 (3x8) :)
【解决方案2】:

你应该使用std::string::size, or std::string::length

sizeof 返回对象的大小,而不是包含的字符数。

【讨论】:

  • std::string::size 和 std::string::length 都返回相同的值。如 6.
  • 是的。它不计算空终止符。
  • @ShameelMohamed 你真的不明白,是吗?
【解决方案3】:

原因是sizeof(buffAsStdStr) 不是字符串的长度而是std::string 实例的大小,并且给定类型的每个实例都具有相同的大小。

sizeof 的结果是在编译过程中确定的,如果你有一个T 类型的对象osizeof(o)sizeof(T) 是等价的。

此外,std::string 不需要存储尾随空字符,并且可以包含“非终止”空字符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 2020-01-10
    • 2014-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多