Reputation: 151
I know these problem which I will be telling you guys,may be very easy but I am really getting trouble while defining string in c++.Earlier I was coding in C language.Where for string I used char array to store string. Now In c++ there are several ways for defining the string and initialization
For example:
1. char str[30];
2.string str="stackoverflow";
3.char *str="stackoverflow";
may be many more..
I also googled but didn't get satisfactory answers.
QUESTIONS 1: Are these definitions of string (which i didn't include ) are same or different ?If yes then how?
QUESTION 2: I have also problem while passing string as function parameter.Are ways of passing string as parameter same in all definitions? If not,Please mention ways too.
QUESTION 3: We know that string terminates with a special character '\0'.What if I defined arr[4] and storing value "vinod" or arr[40] and storing value "vinod"? What about extra memory in second case?Although I haven't tried using program .
Upvotes: 0
Views: 148
Reputation: 2124
Different types of strings:
char str[30];
This creates a modifiable array of 30 chars. It can be used to hold a string but can also be used to hold raw data. It's common for this kind of array to be used as a byte buffer since char is exactly one byte in size.
string str="stackoverflow";
This will create a std::string object passing the string literal "stackoverflow" into it's constructor. std::string will take a copy of this string literal and place it inside an internal modifiable array. std::string is much more powerful than using a plain char array because of all the in-built functionality that comes with it.
char *str="stackoverflow"
This creates a char pointer to a read-only location in memory where the string literal "stackoverflow" lives. This is NOT modifiable and trying to modify it causes undefined behaviour:
char *str="stackoverflow"
str[3] = 'h'; // undefined behaviour
Different ways of passing them as parameters:
As for passing these as parameters then it truly depends on what your goals are. The first type can be passed like so:
void foo(char str[]);
void foo(char* str); // this is valid because arrays decay into pointers.
void foo(const char str[]); // prevents function from modifying the contents of the array.
void foo(const char* str); // same as above.
void foo(const char* const str); // prevents function from modifying contents of the array and what str points to.
The second type can be passed by value or by reference. If you purposefully want to pass a copy of your std::string then you can pass by value. If you want to pass your std::string and not a copy then you pass by reference. If you don't want to pass by reference for performance reasons (to avoid a costly copy) and you don't want the function to modify your string then you can pass by const reference.
void foo(std::string str); // pass by value. A copy is passed into here.
void foo(std::string& str); // pass by reference.
void foo(const std::string& str); // avoid the copy but prevent this function from modifying your string.
The last type should be passed as const since it should not be modified.
void foo(const char* str);
void foo(const char str[]); // this is valid because arrays decay into pointers.
Upvotes: 1
Reputation: 311068
You showed three declarations
1.char str[30];
2.string str="stackoverflow";
3.char *str="stackoverflow"; may be many more..
The first one declares a character array of 30 characters.
The second one declares an object of class std::string
and initializes it with string literal "stackoverflow".
And the third one declares a pointer to char that initialized by the address of the first character of string literal "stackoverflow".
In C++ the last declaration is incorrect because in C++ string literals have types of constant character arrays. It would be correctly to write
3.const char *str="stackoverflow"; may be many more..
So you declared three distinct objects of different types.
Class std::string has a constructor that allows implicitly to convert a pointer to char to an object of type std::string.
So if you have a function with a parameter of type std::string
as for example
void f( std::string s );
then you may pass any of the declared objects above that is
1.
char str[30] = "stackoverflow";
f( str );
2.
std::string str = "stackoverflow";
f( str );
3.
const char *str = "stackoverflow";
f( str );
In all three cases the function will deal within itself with an object of type std::string
.
Upvotes: 0
Reputation: 36503
string str="stackoverflow";
Assuming you mean std::string
, this creates a string literal "stackoverflow" of type const char[]
and then invokes the std::string(const char*)
constructor to create an std::string
object that holds "stackoverflow".
char *str="stackoverflow";
Because a string literal is of type const char[]
, assigning a char*
to it is deprecated and since C++14 illegal, however most compilers still accept it.
It creates a string literal "stackoverflow" on the stack and assigns the address of the first character 's' to the pointer str
.
I have also problem while passing string as function parameter.Are ways of passing string as parameter same in all definitions? If not,Please mention ways too.
In C++ you usually just want to pass a std::string
to a function to avoid breaking stuff. If you want to avoid copying the std::string
object, consider passing const std::string&
.
We know that string terminates with a special character '\0'.What if I defined arr[4] and storing value "vinod" or arr[40] and storing value "vinod"? What about extra memory in second case?
In the first example you're string to store a string literal thats too big for the array to hold, causing buffer overflow.
For arr[40]
, your array is big enough and it'll gladly accept the string literal and store it starting from index 0. The remaining space that isn't needed is still used up.
Upvotes: 0