Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should std::string be used over character arrays?

I sit around and think about whether or not I should be using const char* or const std::string& pretty often when I'm designing class interfaces and when it comes down to it, I often feel like there's 6 in one hand with half a dozen in the other.

Take the following two function prototypes:

void foo(const char* str); void foo(std::string str); 

If the foo function were to store a string, I would say the second is a better option due to the ability to pass a string and utilize move semantics where possible. However, if foo only needed to read the string, would the const char* solution be better?

On a performance perspective, a temporary std::string wouldn't need to be created. However, calling the function with an already existing string as an argument looks obtrusive: foo(mystr.c_str()). Worse yet, if more advanced operations need to be done on the array at some point down the road or if a copy should be stored, the interface then has to change.

So my questions is this:

Are there well defined, either personal or otherwise, conventions that rule when std::string or const char* is a better choice? Furthermore, when starting a new project, is it best to be consistent with usage or just take whichever one fits the current chunk of code best?

like image 936
vmrob Avatar asked Apr 30 '14 08:04

vmrob


People also ask

Should I use string or char array?

In C++ you should in almost all cases use std::string instead of a raw char array. std::string manages the underlying memory for you, which is by itself a good enough reason to prefer it.

Should I use std::string or * char?

Use std::string when you need to store a value. Use const char * when you want maximum flexibility, as almost everything can be easily converted to or from one.

Why do we use std::string?

std::string class in C++ C++ has in its definition a way to represent a sequence of characters as an object of the class. This class is called std:: string. String class stores the characters as a sequence of bytes with the functionality of allowing access to the single-byte character.

Which is faster string or char array?

So the character array approach remains significantly faster although less so. In these tests, it was about 29% faster.


2 Answers

const char* is a throwback to C. I'd say that in decent C++, about the only use for it is in extern "C" APIs.

std::string has a number of advantages:

  1. It provides a constant-time size() function. Discovering the length of a const char* takes linear time.

  2. It is guaranteed to be valid. A const char* has to be checked for being null, and it is entirely possible to pass incorrect data - data missing a null terminator. Such an occurrence is pretty much guaranteed to result in a crash or worse.

  3. It is compatible with standard algorithms.

If you're worried about performance impacts of having to create a std::string to call the function, consider taking the approach the standard library uses - change the function to take a pair of iterators instead. You can then provide a convenience overload taking a const std::string& delegating to the iterator-pair one.

like image 151
Angew is no longer proud of SO Avatar answered Sep 23 '22 17:09

Angew is no longer proud of SO


Just a few notes from personal experience. If you are working on a c++ project (as per the tag you added) stick to the std::string provided as much as you can. Do not try to reinvent the most basic of all structures, the almighty string. I saw several projects where they reinvented the basic string and afterwards spent months fine tuning it.

In case of your c++ project from the moment you have introduced a char* variable you fall back to standard C functions, such as strlen() and strcpy (just to name two ...). And from this point your project starts turning in a mess, with hand managed memory allocation, etc...

In case you need to interact with third party libraries which accept const char* as their parameter (and I suppose you trust those libraries - ie: you trust they do not const_cast away the constness to do evil things with your poor string) you can use std::string::c_str() to get the const char* out of your string.

In case you need to interact with libraries which have methods accepting char* I highly recommend you take a copy of your string's c_str() and use that as the ingoing parameter to the library (of course, do not forget to delete the extra copy).

Beside of these extra points I just subscribe to all three points from Angew's response.

like image 32
Ferenc Deak Avatar answered Sep 19 '22 17:09

Ferenc Deak