3

In the following C++ code, where is s allocated? Does it use heap, data, bss, or some combination? I'm on a Linux/x86 platform in case that makes a difference. Is there a way to have the g++ compiler show me the layout?

#include <string>
#include <iostream>

using namespace std;

string s;

int main()
{
    s = "test";
    cout << s;
}
Ravi
  • 3,718
  • 7
  • 39
  • 57
  • More interesting is why do you want to know. Is there some underlying problem you are trying to solve/understand? – Martin York Dec 09 '10 at 10:35
  • No underlying problem, just wanted to have a better understanding. With built-in types, I think I get it, but with class objects, I wasn't clear what would happen with default constructors and where that memory lives. – Ravi Dec 09 '10 at 22:17

2 Answers2

2

The string 'object' would be in the data segment.

But it will have some dynamic allocations (for holding the actual string characters, for example) on the heap.

EDIT: As correctly commented, a 'string' doesn't HAVE to use dynamic allocations. For example, if the string is short, it may be kept internally. This is implementation dependent.

You can examine the address of the object itself and of pointers it contains to see where things are. If you know the memory mapping of your specific executable, you can tell what lives where.

Hexagon
  • 6,845
  • 2
  • 24
  • 16
2

The C++ Standard doesn't define where the compiler puts such objects, but on UNIX it's reasonable to think that the string data would be either:

  • on the BSS, with the default constructor run before main()
  • on the BSS, with the compiler having determined that all members would be 0 even if the default constructor run, and therefore not running the constructor at all
  • in the data segment, with the default constructor run before main()
  • in the data segment, with the member variables' initial values calculated by the compiler and written directly into the binary image

Given the implementation and members of std::string aren't defined, it's not generally clear whether any members should end up being non-0 after default initialisation, that's why there are so many possibilities.

Compiling on Linux with GCC and no optimisation, then inspecting the executable with "nm -C", I happen to have 's' on the BSS.

 ~/dev  nm -C bss | grep ' s$'
08048896 t global constructors keyed to s
08049c98 B s

man nm

...
       "B" The  symbol  is  in  the  uninitialized data section (known as
           BSS).

While static string objects are never on the heap, one or more pointers they contain may end up pointing at memory on the heap if the string is assigned text too large for any (optional) internal buffer. Again, there's no specific rule to say they won't allocate heap memory for other purposes, or pre-allocate heap for textual content even while still empty (but that would be pretty silly).

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • Some string implementations always allocate on the heap, because they are using the pimpl idiom. – Charles Salvia Dec 09 '10 at 06:08
  • @Charles: good point - it's possible in a std::string implemented for academic purposes, but I've never heard of a real-world std::string implementation using pImpl - the extra cost of indirection would be a major issue. It's a special case in that shipping a new Standard library/STL is such a rare and momentus event that it's almost certain to trigger, and reasonable to require, full client app recompilation - especially as there's a lot of templated and inline code throughout. – Tony Delroy Dec 09 '10 at 06:17
  • Thanks, I tried the nm command, and I also see the string in BSS. Interestingly, I assigned a string to s instead of leaving it default, and the string remained in BSS. I assume this means it's still un-initialized until the constructor is run. – Ravi Dec 09 '10 at 22:27
  • @suravi: Sounds right. The "global constructors keyed to s" symbol grep found above suggests some constructor had to be called even for the default-constructed case, so switching to another constructor was unlikely to move the object (whereas a compiler/std::string implementation where an uninitialised string happened to be 0-filled might create it statically but need to move it should assignment be added). – Tony Delroy Dec 10 '10 at 07:18