Bam
Bam

Reputation: 151

Difference in different way of defining string in c++ and passing these as parameter in function

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

Answers (3)

Mohamad Elghawi
Mohamad Elghawi

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

Vlad from Moscow
Vlad from Moscow

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

Hatted Rooster
Hatted Rooster

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

Related Questions