Hacker News

Hacker News

What changed in MSVC's implementation of std:string from the 2022 copy of RE4B?
1 points by cstyler •                         
I was reading this version of RE4B: https://github.com/Cactus-proj/RE-for-Beginners/releases/tag/v1.0.0

The section about std::string (3.21.4) claims that the MSVC implementation of std::string looks like this:

  struct std_string
  {
      size_t unk1;
      union
      {
          char buf[16];
          char *ptr;
      } u;

      size_t size;     // Mysize
      size_t capacity; // Myres
  };

However this structure is 24 bytes in 32 bit and 32 bytes in 64 bit. Meanwhile the current MSVC std::string is 28 bytes in 32 bit and 40 bytes in 64 bit.

I noticed that the book's implementation is exactly 1 size_t short, so i tried adding a size_t to the top of the struct, and it worked perfectly, as in this dump function now outputs correctly:

#include <string> #include <stdio.h>

struct std_string { union { char buf[16]; char ptr; } u;

    size_t size;     // Mysize
    size_t capacity; // Myres
};

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() { printf("sizeof std string: %d\nours: %d\n\n", sizeof(std::string), sizeof(struct std_string));

    std::string s1 = "a short string";
    std::string s2 = "a string longer than 16 bytes";
    dump_std_string(s1);
    dump_std_string(s2);
};

What has changed and what is that size_t that is now before the string buffer ? Is it some kind of reference counter ?