9

What's the most "proper" way to pass a dynamically sized array to another function?

bool *used = new bool[length]();

I've come up with a few ways that compile but I'm not too sure on what the correct way is.

E.g.

Would these pass by value?

static void test(bool arr[])

static void test(bool *arr)

Would this one pass by reference?

static void test(bool *&arr)

Thanks

john
  • 85,011
  • 4
  • 57
  • 81
noko
  • 1,129
  • 2
  • 14
  • 25

5 Answers5

12

Actually, the two first ideas pass the array by address and the third passes the array by reference. You can devise a little test to check this:

void test1(int* a) {
    a[0] = 1;
}

void test2(int a[]) {
    a[1] = 2;
}

void test3(int *&a) {
    a[2] = 3;
}

int main() {
    int *a = new int[3]();
    a[0] = 0;
    a[1] = 0;
    a[2] = 0;

    test1(a);
    test2(a);
    test3(a);

    cout << a[0] << endl;
    cout << a[1] << endl;
    cout << a[2] << endl;
}

The output of this test is

1
2
3

If a parameter is passed by value, it cannot be modified inside a function because the modifications will stay in the scope of the function. In C++, an array cannot be passed by value, so if you want to mimic this behaviour, you have to pass a const int* or a const int[] as parameters. That way, even if the array is passed by reference, it won't be modified inside the function because of the const property.

To answer your question, the preferred way would be to use a std::vector, but if you absolutely want to use arrays, you should go for int*.

alestanis
  • 21,519
  • 4
  • 48
  • 67
  • 1
    That's using reference in the non-technical sense. Only the third example involves an actual reference. – john Oct 22 '12 at 07:01
  • 1
    I was referring to "pass by reference" as opposed to "pass by value". I thought that was the question. – alestanis Oct 22 '12 at 07:02
  • 1
    Sure, but the first two examples pass a pointer by value which happens to refer to an array. So I would personally say that the first two are examples of pass by value. But it's all just terminology, as long as the OP understands everything is OK. – john Oct 22 '12 at 07:04
  • 1
    that's why I wrote in **bold letters** that the **array** was passed by reference :) – alestanis Oct 22 '12 at 07:07
  • Who downvoted and why? (mostly **why**) This smells like strategic downvoting – alestanis Oct 22 '12 at 07:56
  • The array is **not** passed by reference in the first two examples. The analogy may work in your head, but it's incorrect. – Joseph Mansfield Oct 22 '12 at 07:57
  • Then what's the idiom for the opposite of "passing by value"? – alestanis Oct 22 '12 at 07:58
  • Yes, that would be "passing by reference" but the first two examples are passing a pointer by value. The array doesn't get passed at all. – Joseph Mansfield Oct 22 '12 at 08:02
  • @sftrabbit http://www.learncpp.com/cpp-tutorial/74-passing-arguments-by-address/. Your downvote is unfair. – alestanis Oct 22 '12 at 08:03
  • @sftrabbit take a look at this answer: http://stackoverflow.com/a/430958/1225541 where he says passing by pointer *is* passing by reference. – alestanis Oct 22 '12 at 08:05
  • I've removed the downvote based on the edit. That use of "passing by reference" disguises what is actually happening and confuses the meaning of reference for people new to the language. – Joseph Mansfield Oct 22 '12 at 08:16
  • 1
    Well, people new to the language are taught "passing by value" and "passing by reference". I had never heard of "passing by pointer", and IMHO they get more confused if you explain that you actually are passing a pointer by value and you don't pass the array but you can acces the array through the pointer and... – alestanis Oct 22 '12 at 08:24
  • 1
    Sorry, there is no "pass by pointer". The first two examples are passing a pointer *by value*. The third is passing a pointer *by reference*. None of them pass an array, only a pointer. – Joseph Mansfield Oct 22 '12 at 08:45
  • 1
    That is, in the first two, the pointer is being copied into the function. In the third, it's not and you could modify it from inside. – Joseph Mansfield Oct 22 '12 at 08:46
  • 3
    You didn't `delete` the array... >:( – Elias Kosunen Dec 03 '16 at 19:45
4

You're right. The first two are equivalent and pass a pointer by value. Stylistically the second is preferred as it describes the situation accurately, i.e. you are passing a pointer to your function. The first is a kind of hangover for people who can't quite believe that you can't pass arrays in C++. There is no way to pass an array by value in C++. The third passes a pointer by reference.

There's a confusion here in that in all cases the pointer 'refers' to your array. So when talking about pass by value or pass by reference you should be clear whether you are speaking about the pointer or the array it refers to.

john
  • 85,011
  • 4
  • 57
  • 81
2
static void test(bool arr[])
static void test(bool *arr, size_t size)

For static/dynamic arrays, if you don't want to change location of this pointer.

Example: http://liveworkspace.org/code/c5e379ebe2a051c15261db05de0fc0a9

static void test(bool *&arr)

For dynamic if you want to change location.

Example: http://liveworkspace.org/code/bd03b214cdbe7c86c4c387da78770bcd

But, since you write on C++ - use vectors, instead of raw dynamic arrays.

ForEveR
  • 55,233
  • 2
  • 119
  • 133
1

Use this:

void myFuncThatAcceptsDynamicArrays(bool* array, int size) {
   // Do something (using the size as the size of the array)
}

It is up to the user of the function to provide a valid size (which can be very dangerous).

Mark Garcia
  • 17,424
  • 4
  • 58
  • 94
0

I'd always use vector for dynamic sized arrays. In all cases arrays in C++ are passed by reference since their pointer address only is passed. There is no primitive way to pass by value in case of arrays.

AgA
  • 2,078
  • 7
  • 33
  • 62