Char* VS Std::String in C++

Difference between string and char[] types in C++

A char array is just that - an array of characters:

  • If allocated on the stack (like in your example), it will always occupy eg. 256 bytes no matter how long the text it contains is
  • If allocated on the heap (using malloc() or new char[]) you're responsible for releasing the memory afterwards and you will always have the overhead of a heap allocation.
  • If you copy a text of more than 256 chars into the array, it might crash, produce ugly assertion messages or cause unexplainable (mis-)behavior somewhere else in your program.
  • To determine the text's length, the array has to be scanned, character by character, for a \0 character.

A string is a class that contains a char array, but automatically manages it for you. Most string implementations have a built-in array of 16 characters (so short strings don't fragment the heap) and use the heap for longer strings.

You can access a string's char array like this:

std::string myString = "Hello World";
const char *myStringChars = myString.c_str();

C++ strings can contain embedded \0 characters, know their length without counting, are faster than heap-allocated char arrays for short texts and protect you from buffer overruns. Plus they're more readable and easier to use.


However, C++ strings are not (very) suitable for usage across DLL boundaries, because this would require any user of such a DLL function to make sure he's using the exact same compiler and C++ runtime implementation, lest he risk his string class behaving differently.

Normally, a string class would also release its heap memory on the calling heap, so it will only be able to free memory again if you're using a shared (.dll or .so) version of the runtime.

In short: use C++ strings in all your internal functions and methods. If you ever write a .dll or .so, use C strings in your public (dll/so-exposed) functions.

Difference between std::string and const char*?

std::string will give you the ability to use its member functions and most importantly to modify its contents. The initial data will likely1 be copied to a dynamically allocated memory location when the program reaches its constructor. It will also store its size.

const char* is only a pointer value that points to a constant that is gonna be baked into the binary. There's no size information stored, and all functions operating on it have to rely on the presence of the '\0' value at the end.


1 It's possible that Small-String Optimization kicks in here.

char* vs std::string in c++

You can pass std::strings by reference if they are large to avoid copying, or a pointer to the instance, so I don't see any real advantage using char pointers.

I use std::string/wstring for more or less everything that is actual text. char * is useful for other types of data though and you can be sure it gets deallocated like it should. Otherwise std::vector<char> is the way to go.

There are probably exceptions to all of this.

std::string vs char[] vs char*

is it really that much overhead?

No. In most cases, no. And with C++11's move-semantics, the number of cases (where it used to be overhead) has been greatly reduced. In most cases, people who still prefer char* do so, because of their ignorance. In some, very very rare cases, they may be right in choosing char* over std::string. I'm not counting the cases where you need to call C API, though in many cases you can still use std::string with C API, just use c_str() if the API takes const char*.

Sometime std::string may not be suitable, that doesn't mean char* is the next choice. No, it is not, because std::vector<char> can still be your choice. So you see, there are many choices in C++, before you choose char*.

Note that the number of cases (which is already rare) will be further reduced if the following proposal is accepted by C++ committee for C++1y (maybe, C++14):

  • http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3334.html

Pointer to const char vs char array vs std::string

const char * s1 = "test";
char s2 [] = "test";

These two aren't identical. s1 is immutable: it points to constant memory. Modifying string literals is undefined behaviour.

And yes, in C++ you should prefer std::string.

C++: choosing a `const char *` vs `std::string` when using delegating constructor

"I never asked for this" is a string literal which consists of const char elements:

Foo bar ("I never asked for this"); // calls Foo (const char *in)

Thus, Foo (const char *in) will always get selected by overload resolution regardless of the "order" in which you declare your constructors.

As seen in your 2nd example,

Foo (const char *in) : Foo(std::string (in))

The delegating constructor is selected and will call the target constructor, as selected by the only member of the initialization list.



Related Topics



Leave a reply



Submit