Search code examples
c++arrayspointersstdstring

C++ pass string by reference vs pass char array by reference


Okay so I'm new to C++ and I just wanted to ask why you shouldn't pass the char array by reference with the "&" sign but you should with strings since both arguments are pointers. Example code I have written:

void changeChar(char* buffer, int bSize) {
    strcpy_s(buffer, bSize, "test123");
}

void changeString(string* buffer) {
    *buffer = "test321";
}

char mychar[10] = "hello world";
string mystr;

changeChar(mychar, sizeof(mychar));
changeString(&mystr);

Solution

  • changeChar() takes a char* pointer to a char located somewhere in memory (the function assumes the char* is actually pointing to the 1st char of a char[] array of the specified size).

    Any fixed-length array decays into a pointer to its 1st element when referred to by just its name. So there is no need to (nor can you) use operator& to pass your mychar[] array to your changeChar() function when it takes a char* pointer.

    If you don't want to pass mychar by pointer, you have to pass it by reference instead (otherwise, passing it by value will make a copy of the array, and then the function won't be able to modify the original array). In which case, you must include the array's size as part of the data type used for the reference, eg:

    void changeChar(char (&buffer)[12]) {
        strcpy_s(buffer, 12, "test123");
    }
    
    char mychar[] = "hello world";
    changeChar(mychar);
    

    However, this works only if all arrays passed to the function have the same size. If you need to pass arrays of different sizes, make the function be a template instead so the compiler can deduce the size of the array being passed in, eg:

    template<size_t size>
    void changeChar(char (&buffer)[size]) {
        strcpy_s(buffer, size, "test123");
    }
    
    char mychar[] = "hello world";
    changeChar(mychar);
    

    changeString() takes a string* pointer to a string object located somewhere in memory.

    You can't pass an object by pointer without using operator& (or std::addressof() when a class overrides operator&) to get the address of the object (unless it was allocated with new, which is not the case in your example).

    If you don't want to pass the string object by pointer, you have to pass it by reference instead (otherwise, passing the object by value will make a copy of the object, and the function won't be able to modify the original object):

    void changeString(string &buffer) {
        buffer = "test321";
    }
    
    string mystr;
    changeString(mystr);