Are Vectors Passed to Functions by Value or by Reference in C++

Are vectors passed to functions by value or by reference in C++

In C++, things are passed by value unless you specify otherwise using the &-operator (note that this operator is also used as the 'address-of' operator, but in a different context). This is all well documented, but I'll re-iterate anyway:

void foo(vector<int> bar); // by value
void foo(vector<int> &bar); // by reference (non-const, so modifiable inside foo)
void foo(vector<int> const &bar); // by const-reference

You can also choose to pass a pointer to a vector (void foo(vector<int> *bar)), but unless you know what you're doing and you feel that this is really is the way to go, don't do this.

Also, vectors are not the same as arrays! Internally, the vector keeps track of an array of which it handles the memory management for you, but so do many other STL containers. You can't pass a vector to a function expecting a pointer or array or vice versa (you can get access to (pointer to) the underlying array and use this though). Vectors are classes offering a lot of functionality through its member-functions, whereas pointers and arrays are built-in types. Also, vectors are dynamically allocated (which means that the size may be determined and changed at runtime) whereas the C-style arrays are statically allocated (its size is constant and must be known at compile-time), limiting their use.

I suggest you read some more about C++ in general (specifically array decay), and then have a look at the following program which illustrates the difference between arrays and pointers:

void foo1(int *arr) { cout << sizeof(arr) << '\n'; }
void foo2(int arr[]) { cout << sizeof(arr) << '\n'; }
void foo3(int arr[10]) { cout << sizeof(arr) << '\n'; }
void foo4(int (&arr)[10]) { cout << sizeof(arr) << '\n'; }

int main()
{
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
foo1(arr);
foo2(arr);
foo3(arr);
foo4(arr);
}

Is it faster to pass the pointer to a vector than the vector itself?

Consider the C++ Core Guideline F.16: For “in” parameters, pass cheaply-copied types by value and others by reference to const.

What is cheap and what is expensive to pass by copy depends on some factors. A good rule of thumb is to pass anything as big as a pointer or smaller by value and anything bigger by reference. A std::vector is certainly better passed by const reference instead of making a copy.

You should only pass a pointer instead of a reference when passing a nullptr is a valid parameter. When the caller should always pass a vector and never not a vector then you should prefer references over pointers. References cannot be null, they always refer to an object.


Note that sometimes there is no point in avoiding the copy when the function makes a copy of the argument anyhow. Consider:

 void foo(const std::vector<int>& a) { 
auto copy = a;
// ...
}

Then with

 void foo(std::vector<int> a) {
// a is already a copy
// ...
}

it is more obvious that the function is making a copy, while nothing is saved by passing by reference.

Passing a vector by reference by the values are not changing in original vector which is passed?

vector<int> values is not passing the parameter by reference, but by value. Same issue for the loop (with int value you'll make a copy too). Use &:

void ForEach (vector<int> &values, void (* func )(int), int inc) { // reference for the parameter

for (int & value : values) { // reference for the loop
value += inc;
func (value);
}
}

aside:

  • don't use using namespace std. Use std::vector everywhere instead
  • everytime you see a function parameter like in void ForEach (std::vector<int> values,, wonder if the data is "input" or "output". If it's "input", use a constant reference const std::vector<int> &values to avoid a copy and prevent modification at the same time, if it's "output" do std::vector<int> &values to pass by writable reference.
  • in your loop you can use auto: for (auto & value : values) (will adapt to const too) so if the type changes, you don't have to change your loop.

when should i pass a vector parameter by reference versus passing one by value?

It's far more simpler than your homework suggests, but for the sake of getting the correct marks:

It talks about how the vector will be small, because COPYING a large vector can be costly (performance wise). If your function will not modify the vector, and the vector will be small, then simply passing a copy will do. An example would be a function to print the vector:

void print(const std::vector<int> v) // const because we don't modify v
{
for (auto i : v)
std::cout << i << ", ";
}

When instead we have a function that needs to modify the vector (and those changes need to be observed once the function ends) a reference makes more sense:

void removeDuplicates(std::vector<int>& v)
{
}

Here removeDuplicates takes a non-const reference, because it modifies it. Regardless of the size of the vector, we expect the function to modify the passed in vector:

std::vector<int> v;
// populate v
...
removeDuplicates(v);
// v may now be different

If instead you had a function which modifies the arguments, but those modifications shouldn't be seen outside the function, a non-const copy would suffice. Imagine that our print function printed elements rounded to the nearest 100 (sure we could do that on the fly, but we might alter the vector first and then call our original print).

For real-world advice, you should typically just pass a copy, unless:

* your function is storing a reference the passed parameter, or

* modifying it where changes need to be observed once the function ends

Pass a vector by reference C++

Firstly you need to learn the differences between references and pointers and then the difference between pass-by-reference and pass-by-pointer.

A function prototype of the form:

void example(int *);  //This is pass-by-pointer

expects a function call of the type:

int a;         //The variable a
example(&a); //Passing the address of the variable

Whereas, a prototype of the form:

void example(int &);  //This is pass-by-reference

expects a function call of the type:

int a;       //The variable a
example(a);

Using the same logic, if you wish to pass the vector by reference, use the following:

void funct(vector<string> &vec)  //Function declaration and definition
{
//do something
}

int main()
{
vector<string> v;
funct(v); //Function call
}

EDIT: A link to a basic explanation regarding pointers and references:

https://www.dgp.toronto.edu/~patrick/csc418/wi2004/notes/PointersVsRef.pdf

How to pass a vector to a function by value in C

Arrays decay to a pointer to their first element when passed to a function. This is a convenience feature. There are a few similar cases - functions decay to a pointer to the function when passed, almost anything decays to a bool in a conditional statement. It's just a case of learning these as you go.

There is a solution of sorts to passing an array by value. An instance of a struct will be passed by value, so putting the array in a struct will achieve the desired result.

struct demo
{
int some_array[4];
};

void i_cant_change_it(struct demo x)
{
x.some_array[0] = 42;
}

This is because the struct instance, fortunately, doesn't decay to a pointer when passed to a function. If you want to be able to mutate the instance, such that the caller can see the change, the prototype looks like

void i_might_change_it(struct demo *);

Everything but arrays in c++ are passed by value by default?

By default all function arguments in C++ are passed by value.

Your confusion comes from the fact that the name of an array is actually a pointer to the first element of the array (eg. for the array int a[6], a is a pointer to a[0].

Unless the function parameter is explicitly a reference to a pointer, even pointer arguments are passed by value.



Related Topics



Leave a reply



Submit