If I have a pointer that points to a string variable array of chars
, is there a difference between typing:
char *name = \"name\";
string *name = "name";
Does not compile in GCC.
Yes, there’s a difference. Mainly because you can modify your string but you cannot modify your first version – but the C++ compiler won’t even warn you that this is forbidden if you try.
So always use the second version.
If you need to use a char pointer for whatever reason, make it const
:
char const* str = "name";
Now, if you try to modify the contents of str
, the compiler will forbid this (correctly). You should also push the warning level of your compiler up a notch: then it will warn that your first code (i.e. char* str = "name"
) is legal but deprecated.
char* name = "name"
should be invalid but compiles on most systems for backward compatibility to the old days when there was no const and that it would break large amounts of legacy code if it did not compile. It usually gets a warning though.
The danger is that you get a pointer to writable data (writable according to the rules of C++) but if you actually tried writing to it you would invoke Undefined Behaviour, and the language rules should attempt to protect you from that as much as is reasonably possible.
The correct construct is
const char * name = "name";
There is nothing wrong with the above, even in C++. Using string is not always more correct.
Your second statement should really be
std::string name = "name";
string is a class (actually a typedef of basic_string<char,char_traits<char>,allocator<char>
) defined in the standard library therefore in namespace std (as are basic_string, char_traits and allocator)
There are various scenarios where using string is far preferable to using arrays of char. In your immediate case, for example, you CAN modify it. So
name[0] = 'N';
(convert the first letter to upper-case) is valid with string and not with the char* (undefined behaviour) or const char * (won't compile). You would be allowed to modify the string if you had char name[] = "name";
However if want to append a character to the string, the std::string construct is the only one that will allow you to do that cleanly. With the old C API you would have to use strcat() but that would not be valid unless you had allocated enough memory to do that.
std::string manages the memory for you so you do not have to call malloc() etc. Actually allocator, the 3rd template parameter, manages the memory underneath - basic_string makes the requests for how much memory it needs but is decoupled from the actual memory allocation technique used, so you can use memory pools, etc. for efficiency even with std::string.
In addition basic_string does not actually perform many of the string operations which are done instead through char_traits. (This allows it to use specialist C-functions underneath which are well optimised).
std::string therefore is the best way to manage your strings when you are handling dynamic strings constructed and passed around at run-time (rather than just literals).
You will rarely use a string* (a pointer to a string). If you do so it would be a pointer to an object, like any other pointer. You would not be able to allocate it the way you did.
Yes, the second one isn't valid C++! (It won't compile).
You can create a string
in many ways, but one way is as follows:
string name = "name";
Note that there's no need for the *
, as we don't need to declare it as a pointer.
Yes, char*
is the pointer to an array of character, which is a string. string *
is the pointer to an array of std::string
(which is very rarely used).
string *name = "name";
"name" is a const char*
, and it would never been converted to a std::string*
. This will results compile error.
The valid declaration:
string name = "name";
or
const char* name = "name"; // char* name = "name" is valid, but deprecated
For starters, you probably want to change
string *name = "name";
to read
string name = "name";
The first version won't compile, because a string*
and a char*
are fundamentally different types.
The difference between a string
and a char*
is that the char*
is just a pointer to the sequence. This approach of manipulating strings is based on the C programming language and is the native way in which strings are encoded in C++. C strings are a bit tricky to work with - you need to be sure to allocate space for them properly, to avoid walking off the end of the buffer they occupy, to put them in mutable memory to avoid segmentation faults, etc. The main functions for manipulating them are in <cstring>
. Most C++ programmers advise against the use of C-style strings, as they are inherently harder to work with, but they are still supported both for backwards compatibility and as a "lowest common denominator" to which low-level APIs can build off of.
A C++-style string
is an object encapsulating a string. The details of its memory management are not visible to the user (though you can be guaranteed that all the memory is contiguous). It uses operator overloading to make some common operations like concatenation easier to use, and also supports several member functions designed to do high-level operations like searching, replacing, substrings, etc. They also are designed to interoperate with the STL algorithms, though C-style strings can do this as well.
In short, as a C++ programmer you are probably better off using the string
type. It's safer and a bit easier to use. It's still good to know about C-style strings because you will certainly encounter them in your programming career, but it's probably best not to use them in your programs where string
can also be used unless there's a compelling reason to do so.