4

When I create a std::string member variable in a class, will there be already a default memory allocated when it is instantiated? Or does std::string defer allocation until it is actually used?

I'm using Visual Studio 2010 at the moment, and I noticed, when I create an empty string with:

  std::string s0;
  std::string s1 = "";

Both have capacity == 15 set. So does this mean that it already allocated 15 bytes of memory? If yes, can I prevent this so that no memory is allocated?

Would this be implementation specific across different compilers?

Devolus
  • 20,356
  • 11
  • 56
  • 104
  • Note that there is nothing in the observed behaviour that shows that small string optimization is taking place. – juanchopanza Sep 21 '15 at 13:29
  • _"If yes, can I prevent this so that no memory is allocated?"_ Why? – Lightness Races in Orbit Sep 21 '15 at 14:06
  • Because I have to cache LOTS of structures, along with diagnostic strings and I don't want to waste memory by allocating more than is needed. The alternative is to dynamically allocate the strings if needed. – Devolus Sep 21 '15 at 14:22

4 Answers4

4

The initial capacity of an empty std::string is unspecified by the standard, and is implementation dependent.

Many implementations will allocate an initial capacity of around 16 or so characters (and yes, the capacity refers to allocated memory).

Sander De Dycker
  • 15,403
  • 1
  • 31
  • 37
  • Huh, why? Weird. I mean I get that they expect strings to eventually have characters added to them, but why not defer the allocation until it's really needed? In case it's, y'know, not....? Perhaps they feel that, in the context of ensuring a substantial initial allocation, it's more performant to have an allocation in the constructor, than to run a `if (capacity == 0)` in each and every expansion. – Lightness Races in Orbit Sep 21 '15 at 14:07
  • 1
    @LightnessRacesinOrbit : usually it's done in the context of SSO (ref. [anorm's answer](http://stackoverflow.com/a/32695592/822669)), as is the case eg. in VS starting from VS 2010, and in g++ starting from g++ 5.1 (a good read : http://info.prelert.com/blog/cpp-stdstring-implementations). ie. a small buffer of 16 bytes or so is part of the `std::string` object, avoiding a dynamic memory allocation for small strings, but in turn adding some overhead when the string grows larger. It's a trade-off that improves performance under certain workloads, but decreases it under others. – Sander De Dycker Sep 21 '15 at 14:47
  • @LightnessRacesinOrbit See my answer, its likely that the allocation is a proxy object for iterator validation (and SSO is the reason for capacity==15) which wont exist in a Retail/Release build. – Mike Vine Sep 21 '15 at 15:00
2

I don't have access to VS2010 but have tried this in VS2012 and I'm seeing exactly the same behavior you describe (capacity 15, some memory being allocated)

What is happening (specifically in this case) is that Small String Optimization is giving you a capacity of 15. No memory is being allocated for this.

However, MS's C++ standard library also has additional debug checks which sometimes have to store additional information in the structure so they can run additional checks at runtime for things like iterator validation. You are seeing one of those "proxy" objects being created. In recent versions of VS just running in a default Release Build will turn off those checks. However, if memory serves, turning them off in older builds of Visual Studio was more painful - see _ITERATOR_DEBUG_LEVEL error in visual studio and other related answers for how to turn them off. It may be that you just need a 'Release' build in 2010, alternaticely you may need to mess around with the '_ITERATOR_DEBUG_LEVEL' and '_SECURE_SCL' defines.

Community
  • 1
  • 1
Mike Vine
  • 7,900
  • 21
  • 36
1

Note: This answer is wrong but stackoverflow don't accept deleting accepted answers.

Original answer:

What you're seeing is SSO (small string optimization) in practice. It is indeed implementation specific.

See this answer for more details.

Community
  • 1
  • 1
anorm
  • 2,179
  • 1
  • 17
  • 33
  • I debugged it now and it seems that really malloc is called in this implementation. Thanks for the link. – Devolus Sep 21 '15 at 12:55
  • 2
    I don't think there's anything in OP's post to suggest that they're seeing SSO. One could observe the same in an implementation that doesn't use SSO. – juanchopanza Sep 21 '15 at 13:04
  • @juanchopanza You're right. I'll withdraw my answer. – anorm Sep 21 '15 at 13:34
0

The compiler decides how much memory has to be initialised for the string. Different compilers will allocate different amount of memory would be the common sentence.

Santosh Sahu
  • 1,908
  • 5
  • 24
  • 46