Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

char* vs std::string in c++ [closed]

People also ask

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.

Is char * the same as a string?

The main difference between Character and String is that Character refers to a single letter, number, space, punctuation mark or a symbol that can be represented using a computer while String refers to a set of characters. In C programming, we can use char data type to store both character and string values.

Is string the same as char * in C?

C-strings are simply implemented as a char array which is terminated by a null character (aka 0 ). This last part of the definition is important: all C-strings are char arrays, but not all char arrays are c-strings.

Are C strings faster than std::string?

C-strings are usually faster, because they do not call malloc/new. But there are cases where std::string is faster. Function strlen() is O(N), but std::string::size() is O(1). Also when you search for substring, in C strings you need to check for '\0' on every cycle, in std::string - you don't.


My point of view is:

  • Never use char * if you don't call "C" code.
  • Always use std::string: It's easier, it's more friendly, it's optimized, it's standard, it will prevent you from having bugs, it's been checked and proven to work.

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.


Raw string usage

Yes, sometimes you really can do this. When using const char *, char arrays allocated on the stack and string literals you can do it in such a way there is no memory allocation at all.

Writing such code requires often more thinking and care than using string or vector, but with a proper techniques it can be done. With proper techniques the code can be safe, but you always need to make sure when copying into char [] you either have some guarantees on the lenght of the string being copied, or you check and handle oversized strings gracefully. Not doing so is what gave the strcpy family of functions the reputation of being unsafe.

How templates can help writing safe char buffers

As for char [] buffers safety, templates can help, as they can create an encapsulation for handling the buffer size for you. Templates like this are implemented e.g. by Microsoft to provide safe replacements for strcpy. The example here is extracted from my own code, the real code has a lot more methods, but this should be enough to convey the basic idea:

template <int Size>
class BString
{
  char _data[Size];

  public:
  BString()
  {
    _data[0]=0;
    // note: last character will always stay zero
    // if not, overflow occurred
    // all constructors should contain last element initialization
    // so that it can be verified during destruction
    _data[Size-1]=0;
  }
  const BString &operator = (const char *src)
  {
    strncpy(_data,src,Size-1);
    return *this;
  }

  operator const char *() const {return _data;}
};

//! overloads that make conversion of C code easier 
template <int Size>
inline const BString<Size> & strcpy(BString<Size> &dst, const char *src)
{
  return dst = src;
}

One occasion that you MUST use char* and not std::string is when you need static string constants. The reason for that is that you don't have any control on the order modules initialize their static variables, and another global object from a different module may refer to your string before it's initialized. http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Static_and_Global_Variables

std::string pros:

  • manages the memory for you (the string can grow, and the implementation will allocate a larger buffer you)
  • Higher-level programming interface, works nicely with the rest of STL.

std::string cons: - two distinct STL string instances can not share the same underlying buffer. So if you pass by value you always get a new copy. - there is some performance penalty, but I'd say unless your requirements are special it's negligible.