5

I have his code:

int setAttrib(const string& name, int components){    
    // here I don't even touch 'name'
    if(components == 2) return 3;
    else return 1;
}

And I call the function this way:

setAttrib("position", 3);

I'm profiling memory with xcode profiler and in the function call std::string is making an allocation.
Why is that?

EDIT:

What's the best way to avoid that allocation? since I'm calling that function a lot, and in about 10 seconds of time I end up allocating about 10MB in that line.

Thanks.

Damian
  • 5,471
  • 11
  • 56
  • 89
  • It depends on your compiler. Some compilers will not allocate dynamic memory for such a short string. [http://stackoverflow.com/questions/1466073/how-is-stdstring-implemented](http://stackoverflow.com/questions/1466073/how-is-stdstring-implemented) – Bo Persson May 30 '11 at 11:38

3 Answers3

14

You ask for a const string&, but pass in a const char*. The compiler thus needs to create a temporary object of the correct type.

The fact that "position" is not an std::string but a char const* is more of a historical accident (inherited from C, when there was no string class in C++) than a design decision, but something to keep in mind nevertheless.

Christopher Creutzig
  • 8,656
  • 35
  • 45
  • 1
    +1 Since this is the only response which seems to hit on the key issue: a string literal doesn't have type `std::string`. – James Kanze May 30 '11 at 10:57
  • workaround for "multiple" allocations, is to make static std::string attrName("position") one line before setAttrib("posisition"...) and replace const literal with attrName variable – Kamil Klimek May 30 '11 at 11:40
  • @Kamil: you could even define it in the namespace, as a constant. – Matthieu M. May 30 '11 at 12:02
6

Because std::string typically allocates heap memory to hold the string. In this case, a std::string is implicitly constructed from a string literal (which by itself resides in static storage). Some string implementations use a small buffer to serve small strings, but this doesn't seem to be the case here and is implementation-dependent anyway.

It doesn't matter that name is not used - basically, setAttrib("position", 3) is shorthand for setAttrib(std::string("position"), 3);, so when control enters setAttrib, the memory has already been allocated (of course, in your isolated code sample it would be possible for a compiler to inline getAttrib and then drop the string construction at all, but this is a compiler optimization, not a language feature).

Note that temporary objects created during function invocation are automatically destructed when the function returns, so there is no memory leaked.

Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
  • "and then drop the string construction at all" constructors are never optimized out. They could have side effects a la RAII. – IronMensan May 30 '11 at 14:20
5

In order to call the function the compiler needs to construct all parameters, const string& name included, the only way to do that in your case (you pass a string literal instead) is to construct a temporary std::string and this requires a heap memory allocation in most implementations. It doesn't matter if you use the value inside the function or not.

sharptooth
  • 167,383
  • 100
  • 513
  • 979