简体   繁体   中英

Getting Extra characters at the end when Creating std::string from char*

I have just started learning C++. Now i am learning about arrays. So i am trying out different examples. One such example is given below:

int main()
{
    const char *ptr1 = "Anya";
    char arr[] = {'A','n','y','a'};
    
    std::string name1(ptr1); //this works 
    std::cout << name1 << std::endl;
    
    std::string name2(arr); 
    std::cout << name2 << std::endl; //this prints extra characters at the end?
    return 0;
}

In the above example at the last cout statement i am getting some extra characters at the end. My question is that how can i prevent this from happening in the above code and what is wrong with the code so that i don't make the same mistake in future?

The problem is that you're constructing a std::string using a non null terminated array as explained below.

When you wrote:

char arr[] = {'A','n','y','a'}; //not null terminated

The above statement creates an array that is not null terminated .

Next when you wrote:

std::string name2(arr); //undefined behavior

There are 2 important things to note about the above statement:

  1. arr decays to a char* due to type decay .
  2. This char* is passed as an argument to a std::string constructor that have a parameter of type const char* . Essentially the above statement creates a std::string object from a non null terminated array.

But note that whenever we create a std::string using a const char* , the array to which the pointer points must be null terminated. Otherwise the result is undefined behavior .

Undefined behavior means anything 1 can happen including but not limited to the program giving your expected output. But never rely (or make conclusions based) on the output of a program that has undefined behavior.

For example here the program gives expected output but here it doesn't. So as i said, don't rely on the output of a program that have UB.

Solution

You can solve this by making your array null terminated as shown below.

char arr[] = {'A','n','y','a','\0'}; //arr is null terminated
// char arr[] = "Anya";              //this is also null terminated

1 For a more technically accurate definition of undefined behavior see this where it is mentioned that: there are no restrictions on the behavior of the program .

char arr[] = {'A','n','y','a'}; is not null terminated so you will read it out of bounds when creating the string which in turn makes your program have undefined behavior (and could therefore do anything).

Either make it null terminated:

char arr[] = {'A','n','y','a','\0'};

Or, create the string from iterators:

#include <iostream>
#include <iterator>
#include <string>

int main() {
    char arr[] = {'A', 'n', 'y', 'a'};

    std::string name2(std::begin(arr), std::end(arr));
    std::cout << name2 << '\n';   // now prints "Anya"
}

Or create it with the constructor taking the length as an argument:

    std::string name2(arr, sizeof arr); // `sizeof arr` is here 4

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM