简体   繁体   中英

How can I pass an array by reference to a function in C++?

I have the following program where two variables are to be passed by reference to a function where their values will be determined based on external factors before being returned to main() so that they can be used by other functions. The first variable I am trying to pass is an int , and that goes fine, but the other is an array of strings, which is causing me some problems.

I've done enough research into this to know that you can't have an array or references (though I've yet to figure out why) and I was wondering if anyone could help me figure out how to do this? The various methods I've tried have all resulted in segmentation faults .

NB : The code below has the array being passed by value since I just don't know what to write for it.

Update : I'm required to use an array for my coursework. Some other data structure, such as the vector that has been suggested, would be great, but I have to use specific structures.

void initialise_existing_devices(int& no_of_existing_devices, string existing_devices[100]);

int main()
{
    int no_of_existing_devices = 0;
    string existing_devices[100];

    initialise_existing_devices(no_of_existing_devices, existing_devices[100]);
}

void initialise_existing_devices(int& no_of_existing_devices, string existing_devices[100])
{
    string line;
    ifstream DeviceList;
    DeviceList.open("devices/device_list");
    while (true)
    {
        getline(DeviceList, line, '\n');
        if (DeviceList.eof())
        {
            break;
        }
        ++ no_of_existing_devices;
    }
    DeviceList.close();

    DeviceList.open("devices/device_list");
    for (int i = 0; i < no_of_existing_devices; i ++)
    {
        getline(DeviceList, line, '\n');
        existing_devices[i] = line;
    }
}

A reference to an array looks like:

void f(std::string (&a)[N]) { }

where a is the name of the parameter and N is the number of elements in the array.


However, usually in C++ you don't pass an array by reference (you can; it's just not common). Other options include:

  • Pass a pointer to the initial element of the array; in this case, consider passing the size of the array as a second argument to the function.

  • Use a std::vector<std::string> or a std::array<std::string, N> instead and pass it by reference (you can also find the array psuedo-container in Boost; barring that, consider writing your own. If you take a look at the Boost source code, it's quite simple and straightforward).

  • Pass a pair of iterators (begin and end) to the function and use them to manipulate the range.

The last option is the most idiomatic C++ approach; it is also the most generic because you can use any type of container, including arrays, standard library containers, or containers that you've written yourself.


Since you are actually trying to use the parameter as an "out" parameter, it's probably better just to return a std::vector<string> or a std::array<string, 100> containing the results; this is much cleaner.

this line is not doing what you are expecting:

initialise_existing_devices(no_of_existing_devices, existing_devices[100])

hint: array index, 100 ...

I would suggest that you use a std::vector<std::string> rather than the array and pass that by reference.

EDIT: okay, given the update:

can you use a struct ? If so, you can wrap the array in a struct :

struct string_array
{
  string data[100];
};

and then define an instance of this in main, and pass that by reference? I'm sure you can fill in the details.. :)

You should use a std::vector<T> for heap-managed arrays or a boost:: / std::array<T, N> for stack-based arrays. These objects will hold their own size.

For the actual argument, use just the array name, which represents the address of the array:

initialise_existing_devices(no_of_existing_devices, existing_devices);

For the parameter, use this for a constant pointer to the array:

void initialise_existing_devices(int& no_of_existing_devices, string existing_devices[])

That said, using a std::vector as the return type or a reference parameter would avoid the need to guess the number of devices before the call.

This is one of those things C++ has in common with C. Arrays are not passed by value. They're demoted to pointers to their first elements. The array syntax in the function parameters is essentially just a comment. You can tell by doing a sizeof(existing_devices) inside your function call. So the answer to your question is that you're already doing it.

You can use templates, like so:

template <size_t size> 
initialise_existing_devices(int& no_of_existing_devices, string (&existing_devices)[size])
{
}

or you can do:

typedef string hundred_strings[100];

initialise_existing_devices(int& no_of_existing_devices, hundred_strings &existing_devices)
{
}

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