Why should one use std::string over c-style strings in C++?
Asked Answered
N

6

16

"One should always use std::string over c-style strings(char *)" is advice that comes up for almost every source code posted here. While the advice is no doubt good, the actual questions being addressed do not permit to elaborate on the why? aspect of the advice in detail. This question is to serve as a placeholder for the same.

A good answer should cover the following aspects(in detail):

  1. Why should one use std::string over c-style strings in C++?
  2. What are the disadvantages (if any) of the practice mentioned in #1?
  3. What are the scenarios where the opposite of the advice mentioned in #1 is a good practice?
Noni answered 5/4, 2012 at 3:1 Comment(3)
I do plan to tag this c++-Faq & will discuss the same in C++ Lounge shortly.Noni
This is still being asked in 2012?! Also, when is the advice to use std::string ever not accompanied by rationalization?Impostume
@KarlKnechtel: Sorry, Seems I am a C++ novice unlike you :) However,I would bother reading the entire question & understanding the purpose behind it rather than just reading the title before commenting.Noni
G
16
  1. std::string manages its own memory, so you can copy, create, destroy them easily.
  2. You can't use your own buffer as a std::string.
  3. You need to pass a c string / buffer to something that expects to take ownership of the buffer - such as a 3rd party C library.
Gaultiero answered 5/4, 2012 at 3:5 Comment(0)
U
4

Well, if you just need an array of chars, std::string provides little advantage. But face it, how often is that the case? By wrapping a char array with additional functionality like std::string does, you gain both power and efficiency for some operations.

For example, determining the length of an array of characters requires "counting" the characters in the array. In contrast, an std::string provides an efficient operation for this particular task. (see https://mcmap.net/q/169826/-how-is-std-string-implemented)

  1. For power, efficiency and sanity
  2. Larger memory footprint than "just" a char array
  3. When you just need an array of chars
Ulcerous answered 5/4, 2012 at 3:12 Comment(0)
V
3

3) The advice always use string of course must be taken with a pinch of common sense. String literals are const char[], and if you pass a literal to a function that takes a const char* (for example std::ifstream::open()) there's absolutely no point wrapping it in std::string.

Violaceous answered 5/4, 2012 at 7:54 Comment(0)
O
2

Why should one use std::string over c-style strings in C++?

The main reason is it frees you from managing the lifetime of the string data. You can just treat strings as values and let the compiler/library worry about managing the memory.

Manually managing memory allocations and lifetimes is tedious and error prone.

What are the disadvantages (if any) of the practice mentioned in #1?

You give up fine-grained control over memory allocation and copying. That means you end up with a memory management strategy chosen by your toolchain vendor rather than chosen to match the needs of your program.

If you aren't careful you can end up with a lot of unneeded data copying (in a non-refcounted implementation) or reference count manipulation (in a refcounted implementation)

In a mixed-language project any function whose arguments use std::string or any data structure that contains std::string will not be able to be used directly from other languages.

What are the scenarios where the opposite of the advice mentioned in #1 is a good practice?

Different people will have different opinions on this but IMO

  • For function arguments passing strings in "const char *" is a good choice since it avoids unnessacery copying/refcouning and gives the caller flexibility about what they pass in.
  • For things used in interoperation with other languages you have little choice but to use c-style strings.
  • When you have a known length limit it may be faster to use fixed-size arrays.
  • When dealing with very long strings it may be better to use a construction that will definately be refcounted rather than copied (such as a character array wrapped in a shared_ptr) or indeed to use a different type of data structure altogether
Oxide answered 26/7, 2016 at 13:22 Comment(0)
S
1

A char* is basically a pointer to a character. What C does is frequently makes this pointer point to the first character in an array.

An std::string is a class that is much like a vector. Internally, it handles the storage of an array of characters, and gives the user several member functions to manipulate said stored array as well as several overloaded operators.

Reasons to use a char* over an std::string:

C backwards-compatibility.
Performance (potentially).
char*s have lower-level access.

Reasons to use an std::string over a char*:

Much more intuitive to use.
Better searching, replacement, and manipulation functions.
Reduced risk of segmentation faults.

Example :

char* must be used in conjuction with either a char array, or with a dynamically allocated char array. After all, a pointer is worthless unless it actually points to something. This is mainly used in C programs:

char somebuffer[100] = "a string";
char* ptr = somebuffer;  // ptr now points to somebuffer
cout << ptr; // prints "a string"
somebuffer[0] = 'b';  // change somebuffer
cout << ptr;  // prints "b string" 

notice that when you change 'somebuffer', 'ptr' also changes. This is because somebuffer is the actual string in this case. ptr just points/refers to it.

With std::string it's less weird:

std::string a = "a string";
std::string b = a;
cout << b;  // prints "a string"
a[0] = 'b';  // change 'a'
cout << b;  // prints "a string" (not "b string") 

Here, you can see that changing 'a' does not affect 'b', because 'b' is the actual string.

But really, the major difference is that with char arrays, you are responsible for managing the memory, whereas std::string does it for you. In C++, there are very few reasons to use char arrays over strings. 99 times out of 100 you're better off with a string.

Until you fully understand memory management and pointers, just save yourself some headaches and use std::string.

Sarre answered 10/8, 2012 at 21:15 Comment(2)
I doubt the claim about better performance of C strings. It does have less memory overhead which may be crucial if you have lots of small strings (e.g. in parsing or bioinformatics, where std::string may be prohibitive).Hirudin
Using char* gives you more control over what is happening "behind" the scenes, which means you can tune the performance if you need to.Sarre
T
-1

In general you should always use std::string, since it is less bug prone. Be aware, that memory overhead of std::string is significant. Recently I've performed some experiments about std::string overhead. In general it is about 48 bytes! The article is here: http://jovislab.com/blog/?p=76.

Toro answered 13/4, 2012 at 17:35 Comment(4)
A pity that small string optimization is a great thing.Zakarias
It all depends on the implementation. But in practice, without debug stuff, the overheard should be insignificant.Mechellemechlin
It is significant. With -O2 and without any -g, G++ still takes 24 bytes for a a on-byte string. I suppose the same is for Visual Studio.Toro
@asanoki: Using my code at ideone.com/ynJhF (allocating 1000000 strings totaling a length of 7,502,096 chars), VC++10 allocated 38,712kb for both char* and unique_ptr, and allocated 27,428kb for string. (That's a 41% savings). G++ 4.5.4 allocated 23,052kb for both char* and unique_ptr, and allocated 33,832kb for string (That's 47% extra space).Pricket

© 2022 - 2024 — McMap. All rights reserved.