Performance Expectations of std::string’s c_str() in C++

cperformancestrings

I've been doing some needed optimizations lately. One thing I've been doing is changing some ostringstreams -> sprintfs. I'm sprintf'ing a bunch of std::strings to a c style array, ala

char foo[500];
sprintf(foo, "%s+%s", str1.c_str(), str2.c_str());

It turns out that Microsoft's std::string::c_str() implementation runs in constant time (it just returns an internal pointer). It appears that libstdc++ does the same. I realize the std makes no guarantees for c_str, but its hard to imagine another way of doing this. If, for example, they copied into memory they'd either have to allocate memory for a buffer (leaving it up to the caller to destroy it — NOT part of the STL contract) OR they'd have to copy to an internal static buffer (probably not threadsafe, and you have no guarantees on its lifetime). So simply returning a pointer to an internally maintained null terminated string seems to be the only realistic solution.

Best Answer

If I recall, the standard allows string::c_str() to return pretty much anything that satisfies:

  • Storage which is large enough for the contents of the string and the terminating NULL
  • Must be valid until a non-const member of the given string object is called

So in practice, this means a pointer to the internal storage; as there is no way to externally track the life of the returned pointer. I think your optimisation is safe to assume this is (small) constant time.

On a related note, if string formatting is performance limiting; you may find better luck deferring the evaluation until absolutely needed with something like Boost.Phoenix.

Boost.Format I believe defers the formatting internally until the result is required, and you can use the same format object repeatedly without re-parsing the format string, which I've found to make a significant difference for high-frequency logging.

Related Topic