Pass a char array to a function that expects a const std::string reference


atomSmasher

I've made a mistake with a socket interface that I've been writing for a while , and I just noticed this while browsing through the code to find another problem. The socket receives a string and passes it to jsoncpp to complete the json parsing. I can almost understand what's going on here, but I can't. I want to know the actual situation. Here is a minimal example:

#include <iostream>
#include <cstring>

void doSomethingWithAString(const std::string &val) {
    std::cout << val.size() << std::endl;
    std::cout << val << std::endl;
}

int main()
{
    char responseBufferForSocket[10000];
    memset(responseBufferForSocket, 0, 10000);

    //Lets simulate a response from a socket connection
    responseBufferForSocket[0] = 'H';
    responseBufferForSocket[1] = 'i';
    responseBufferForSocket[2] = '?';

    // Now lets pass a .... the address of the first char in the array...
    // wait a minute..that's not a const std::string& ... but hey, it's ok it *works*!
    doSomethingWithAString(responseBufferForSocket);

    return 0;
}

The code above doesn't cause any obvious problems, but if there is a problem, I'd like to correct it. Obviously the character array is being converted to a string, but by what mechanism? I think I have four questions:

  1. Is this string converted on the stack and passed by reference or by value?
  2. Are you using operator= overload? "from c string" constructor? Other mechanism?
  3. Is 2-based less efficient than explicitly converting to a string using the constructor?
  4. Is this dangerous? :)

Compiled with g++ (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609

Etienne de Martel

std::stringhas a non-explicit constructor (i.e. not marked with a explicitkeyword ) that takes one const char*argument and copies characters up to the first character '\0'(if no such character exists in the string, the behavior is undefined) . In other words, it performs a copy of the source data. #5 reload on this page .

const char[]The implicit decay is const char*that you can pass temporary variables to functions with constreference parameters . constBy the way, this only works if the reference is ; if you can't use constit, pass it by value.

So when you pass a const char[]to that function, an object of temporary type is std::stringconstructed using that constructor and bound to that parameter. The temporary will remain alive for the duration of the function call and will be destroyed on return.

With all of this in mind, let's address your questions:

  1. It is passed by reference, but the reference is to a temporary object.
  2. Constructor because we are constructing an object. std::stringThere is also operator=a const char*parameter, but it is never used for implicit conversion: you need to assign something explicitly.
  3. Since the same code is run, the performance is the same, but it does incur some overhead due to copying the data instead of referencing it. If this is an issue, std::string_viewuse instead.
  4. It's safe as long as you don't try to keep references to parameters or pointers to the time before the function call, as the object may not be alive after that (but you should always keep this in mind when using reference parameters). You also need to make sure that the C string you pass is correctly null terminated.

Related


How to pass char to a function that expects a string

Neil Kirk I want to pass char to a parameter that expects a string. void test(const string&); test('a'); // does not like error: invalid user-defined conversion from ‘char’ to ‘const string& {aka const std::basic_string<char>&}’ I know I can change 'to', but

Pass const char instead of std::string as function parameter

Abruzzo Forte and Gentile This is a newbie question, but I don't understand how it works. Suppose I have the following function void foo(const std::string& v) { cout << v << endl; } and the call in my program below. foo("hi!"); Essentially, I'm passing a

std::string and const char*

Martin Perry if i use const char * str = "Hello"; No memory allocation/deallocation required at runtime if i use const std::string str = "Hello"; Will allocation be done in the string class via new/malloc? I can find it in assembly, but I'm not very good at

std::string and const char*

Martin Perry if i use const char * str = "Hello"; No memory allocation/deallocation required at runtime if i use const std::string str = "Hello"; Will allocation be done in string class via new/malloc? I can find it in assembly, but I'm not very good at read

std::string and const char*

Martin Perry if i use const char * str = "Hello"; No memory allocation/deallocation required at runtime if i use const std::string str = "Hello"; Will allocation be done in the string class via new/malloc? I can find it in assembly, but I'm not very good at

std::string and const char*

Martin Perry if i use const char * str = "Hello"; No memory allocation/deallocation required at runtime if i use const std::string str = "Hello"; Will allocation be done in string class via new/malloc? I can find it in assembly, but I'm not very good at read

std::string and const char*

Martin Perry if i use const char * str = "Hello"; No memory allocation/deallocation required at runtime if i use const std::string str = "Hello"; Will allocation be done in the string class via new/malloc? I can find it in assembly, but I'm not very good at

How to convert "std::vector<std::string>" to "const char *array"?

Lemon Candy There is a function that takes a const char* array, basically a list of words. Since this list of words may change, I cannot declare and initialize this array at program startup. Now, I have a vector of strings that I need to convert to a const cha

How to convert "std::vector<std::string>" to "const char *array"?

Lemon Candy There is a function that takes a const char* array, basically a list of words. Since this list of words may change, I cannot declare and initialize this array at program startup. Now, I have a vector of strings that I need to convert to a const cha

How to pass std::string_view by value or const reference

gap Typically string_viewused for the following function parameters: void fval(std::string_view sv); void fcref(std::string_view const &sv); Which is better? A const reference is 8 bytes, string_viewusually twice that, say 16 bytes. However, if not inlined or

How to pass std::string_view by value or const reference

gap Typically string_viewused for the following function parameters: void fval(std::string_view sv); void fcref(std::string_view const &sv); Which is better? A const reference is 8 bytes, string_viewusually twice that, say 16 bytes. However, if not inlined or

How to pass std::string_view by value or const reference

gap Typically string_viewused for the following function parameters: void fval(std::string_view sv); void fcref(std::string_view const &sv); Which is better? A const reference is 8 bytes, string_viewusually twice that, say 16 bytes. However, if not inlined or

How to pass std::string_view by value or const reference

gap Typically string_viewused for the following function parameters: void fval(std::string_view sv); void fcref(std::string_view const &sv); Which is better? A const reference is 8 bytes, string_viewusually twice that, say 16 bytes. However, if not inlined or

How to pass std::string_view by value or const reference

gap Typically string_viewused for the following function parameters: void fval(std::string_view sv); void fcref(std::string_view const &sv); Which is better? A const reference is 8 bytes, string_viewusually twice that, say 16 bytes. However, if not inlined or

Pass by reference to char array

User 13851309 Here is my code. int main(int argc, char *argv[]) { int shmid; char *shmc; char *shmp; pid_t pid; shmid = shmget(IPC_PRIVATE, 3 * sizeof(char), 0666 | IPC_CREAT); pid = fork(); if (pid == 0) { shmc = (c

Pass unsigned char array to string function

username Say I have some utf8 encoded strings. In it, use to separate words ";". But every character (except ) in ";"this string has a utf8 value greater than 128 . Suppose I store this string in unsigned charan array: unsigned char buff[]="someutf8string;sepa