如何 sizeof(std::cout) 是 140 而 sizeof(std::string) 只有 4?
How sizeof(std::cout) is 140 whereas sizeof(std::string) is only 4?
考虑以下程序:
#include <iostream>
int main()
{
std::cout<<sizeof(std::string)<<'\n';
std::cout<<sizeof(std::ostream)<<'\n';
std::cout<<sizeof(std::istream)<<'\n';
std::cout<<sizeof(std::cout);
}
我的编译器 (g++ 4.8.1) 的输出是
4
140
144
140
输出结果让我很困惑。为什么 sizeof string
class 只有 4 个字节,对于 ostream 和 istream 它分别给出 140 和 144 个字节? sizeof(std::cout)
是 140 个字节,与 sizeof(std::ostream)
相同。所以,我认为因为 cout
对象是 ostream
类型,所以我在这里得到相同的输出。正确的?这些大小是否依赖于编译器?
基本上归结为 iostream 有相当多的状态要存储,而字符串却很少。
尽管如此,字符串的大小仅为 4 的想法有点令人惊讶(至少对我而言)。我通常期望 32 位实现为 12,64 位版本为 24。
特别是,一个字符串通常包含三样东西:一个指向用于保存数据的实际缓冲区的指针(通常分配在空闲存储上),一个 size_t 用于包含该缓冲区的大小,以及a size_t 包含当前存储的字符数。在典型情况下,每一个在 32 位实现上都是 32 位,在 64 位实现上都是 64 位。
完全有可能证明一个比它大一些的字符串对象也是合理的——例如,将一个小字符串的数据直接存储在字符串对象本身中是相当常见的 ("short string optimization")。在这种情况下,您可能 space 用于(最多)字符串对象本身中的 20 个字符,这通常会进一步增加其大小。
考虑以下程序:
#include <iostream>
int main()
{
std::cout<<sizeof(std::string)<<'\n';
std::cout<<sizeof(std::ostream)<<'\n';
std::cout<<sizeof(std::istream)<<'\n';
std::cout<<sizeof(std::cout);
}
我的编译器 (g++ 4.8.1) 的输出是
4
140
144
140
输出结果让我很困惑。为什么 sizeof string
class 只有 4 个字节,对于 ostream 和 istream 它分别给出 140 和 144 个字节? sizeof(std::cout)
是 140 个字节,与 sizeof(std::ostream)
相同。所以,我认为因为 cout
对象是 ostream
类型,所以我在这里得到相同的输出。正确的?这些大小是否依赖于编译器?
基本上归结为 iostream 有相当多的状态要存储,而字符串却很少。
尽管如此,字符串的大小仅为 4 的想法有点令人惊讶(至少对我而言)。我通常期望 32 位实现为 12,64 位版本为 24。
特别是,一个字符串通常包含三样东西:一个指向用于保存数据的实际缓冲区的指针(通常分配在空闲存储上),一个 size_t 用于包含该缓冲区的大小,以及a size_t 包含当前存储的字符数。在典型情况下,每一个在 32 位实现上都是 32 位,在 64 位实现上都是 64 位。
完全有可能证明一个比它大一些的字符串对象也是合理的——例如,将一个小字符串的数据直接存储在字符串对象本身中是相当常见的 ("short string optimization")。在这种情况下,您可能 space 用于(最多)字符串对象本身中的 20 个字符,这通常会进一步增加其大小。