0

SSO enables short strings to be stored on stack. What if I have a std::map<std::string, std::string> (or any std container for that matter) which consists mainly of short strings (1 to 10 characters), and it grows to a big size (let's say 200,000 pairs). With average length of 5, this will take up around 2 MB on characters alone, which is more than enough to cause stack overflow if SSO will work for all the strings.

So the question is: how likely is the stack overflow? How exactly SSO will work in that case (MinGW 6.0, C++14, Windows 10 x64 machine)?

5
  • 2
    Completely unlikely. Feel free to create a map with a million string keys. It won't use any more stack space than a completely empty map. Commented Jun 6, 2023 at 14:11
  • While SSO stores the data locally, in the string, the data itself (the string object) is already stored in the heap as that is where std::map allocated its node. Commented Jun 6, 2023 at 14:14
  • The string data will be stored on the stack with SSO only if the string object itself is on the stack. This is not the case for strings in containers like vector and map where the elements are on the heap.
    – interjay
    Commented Jun 6, 2023 at 14:14
  • You've already paid the price of SSO by using a std::string. It's own static size is what controls how many character it can support using SSO. Commented Jun 6, 2023 at 14:15
  • So the question is: how likely is the stack overflow? -- struct S { char foo[20]; }; -- S *pS = new S; -- Is the foo array in pS on the stack or heap? Commented Jun 6, 2023 at 14:17

1 Answer 1

5

Your notion of "stored on the stack" is wrong. The std::map allocates its elements dynamically. Whether the std::string will dynamically allocate the characters is then not that relevant anymore.

What you store on the stack is sizeof(std::map<std::string,std::string>) and that is a compile time constant. It does not change with number of elements or length of the strings.

8
  • I did not understand that SSO applied only to statically created strings. That makes it clear
    – GaussGun
    Commented Jun 6, 2023 at 14:18
  • 1
    @GaussGun SSO applies to all strings. An object does not know if it lives on the stack or on the heap. sizeof(std::string) or in general sizeof(any_type) is a compile time constant Commented Jun 6, 2023 at 14:20
  • then I am confused again. If SSO is applied, it doesn't necessarily mean that the string is stored on stack?
    – GaussGun
    Commented Jun 6, 2023 at 14:30
  • @GaussGun no. You would not, but you can auto* x = new std::string;. Nothing is stored on the stack here. And the string does not care. It will do SSO as usual. The size occupied the stack of a std::map is always the same. In general the sizeof(T) is a constant for any type T Commented Jun 6, 2023 at 14:39
  • @GaussGun suppose you would manually manage a dynamically allocated array via a raw pointer (you should not!). Then you do string* x = new string[42]; to have an array of 42 strings. What is stored on the stack is a single pointer. Thats not what the map does, but it is similar enough to understand that adding characters to the string does not affect how much memory the array or the map occupies on the stack Commented Jun 6, 2023 at 14:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.