返回介绍

MSVC

发布于 2025-02-22 14:00:51 字数 1200 浏览 0 评论 0 收藏 0

MSVC 的实现中,字符串存储在适当的位置,不一定位于指针指向的缓冲区(如果字符串的长度小于 16 个字符)。 这意味着短的字符串在 32 位环境下至少占据 16+4+4=24 字节的空间,在 64 位环境下至少占据 16+8+8=32 字节,当字符串长度大于 16 字符时,相应的需要增加字符串自身的长度。

#include <string>
#include <stdio.h>
struct std_string
{
union
{
char buf[16];
char* ptr;
} u;
size_t size; // AKA ’Mysize’ in MSVC
size_t capacity; // AKA ’Myres’ in MSVC
};
void dump_std_string(std::string s)
{
struct std_string *p=(struct std_string*)&s;
printf ("[%s] size:%d capacity:%d\n", p->size>16 ? p->u.ptr : p->u.buf, p->size, p->
capacity);
};
int main()
{
std::string s1="short string";
std::string s2="string longer that 16 bytes";
dump_std_string(s1);
dump_std_string(s2);
// that works without using c_str()
printf ("%s\n", &s1);
printf ("%s\n", s2);
};

通过源代码可以清晰的看到这些。 如果字符串长度小于 16 个符号,存储字符的缓冲区不需要在堆上分配。实际上非常适宜这样做,因为大量的字符串确实都较短。显然,微软的开发人员认为 16 个字符是好的临界点。 在 main 函数尾部,虽然没有使用 c_str() 方法,但是如果编译运行上面的代码,所有字符串都将打印在控制台上。 当字符串的长度小于 16 个字符时,存储字符串的缓冲区位于 std::string 对象的开始位置,printf 函数将指针当做指向以 0 结尾的字符数组,因此上述代码可以正常运行。 第二个超过 16 字符的字符串的打印方式比较危险,通常程序员犯的错误是忘记写 c_str()。这在很长的一段时间不会引起人的注意,直到一个很长的字符串出现,然后程序崩溃。而上述代码可以工作,因为指向字符串缓冲区的指针位于结构体的开始。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文