Search code examples
c++stringstl

Copy happened when pass char * to string?


I need to call a function, whose parameters are type string.

I thought std::string is a good choice, because it provide a lot of interface.

But recently, I found there is a copy happened when i pass char * to const std::string &.

here is the code:

#include <iostream>
#include <string>
         
using namespace std;
         
void test_string(const std::string & s) {
  printf("%p\n", s.data());
}        
         
int main() {
  char aa[] = "asd";
  test_string(aa);
  printf("%p\n", aa);
}

As the above code shows, I can pass std::string and char [] to my function test_string.

And my arg type is const std::string &, I thought it would be no copy happened.

But the output shows the address is different, I think the function construct a tempory variable string, which copy from my char [] one by one. which is not neccessary.

Is this a bad usage (pass char[] to std::string)? Is there any good advice to avoid copy?


Solution

  • aa is a char array, not a std::string, and so a temporary std::string object is constructer to be passed by reference (as s) into test_string.

    When this temporary object is constructed a copy is made (a std::string always owns the data).

    If you change aa to be a std::string, no copy will be done and it will be passed by reference.

    Alternativly change test_string to accept a std::string_view. A std::string_view does not make a copy when it is constructed (it is just a non-owning view into an existing string and can be constructed from a char array as well as from another std::string).
    As all view types (which ar lightweight), you should by default pass std::string_view by value.
    This article explains it in more details: Three reasons to pass std::string_view by value.