0

I'm trying to pass an array as a pointer to a function, but when I do that the function only sees the pointer as an array with 1 variable. Here is my code:

void make3(int* a) {
    int n = sizeof(a) / sizeof(a[0]);
    for (int i = 0; i < n; i++) {a[i] = 3;}
}
int main()
{
    int a[3] = { 0, 1, 2 };
    make3(a);
    int* b = a;
    for (int i = 0; i < sizeof(a)/sizeof(a[0]); i++) {
        cout << *(b + i) << endl;
    }
}

The function make3 only changes the first value of the array to 3, instead of all of them. Is this normal? If not, what am I doing wrong?

5
  • 1
    int a[3] is an array;. int* a is a pointer. An array will decay to a pointer, but regardless an array is not a pointer. What you are doing wrong is you are not using a std::vector. Commented Nov 20, 2021 at 12:43
  • @Eljay It's supposed to be a simple array, which is why i can't use vector. But thank you! Commented Nov 20, 2021 at 12:46
  • can you explain why you specifically need to pass the array as a pointer and why you cannot afford to pass the size as argument ? Commented Nov 20, 2021 at 12:47
  • A pointer is not actually an array. In your example, make3() is only passed the address of the first element of the array passed by main(). The function has no way in standard C++ to obtain the number of elements in that array. If you need to obtain the size (number of elements) you need to pass it in some way (e.g. as an additional argument) or, as Elijay said, use std::vector (which is a data structure with member function, so you can obtain the size). If you can't use std::vector, must pass a pointer, but you can't pass the size somehow, there is NO WAY to get the size. Commented Nov 20, 2021 at 12:57
  • Many of the answers and comments suggest std::vector which is an excellent replacement. However for these specific use cases (known fixed size) there is also std::array. Commented Nov 20, 2021 at 13:47

2 Answers 2

3

When you pass an array to a function, it decays to a pointer.

int n = sizeof(a) / sizeof(a[0]);

Gets evaluated to

int n = sizeof(int*) / sizeof(int);

Which is 1 (when sizeof(int*) is 4 - depends on inplementation).

You should pass the array size as an argument instead:

void make3(int* a, int n) {
    for (int i = 0; i < n; i++) {a[i] = 3;}
}

int main()
{
    int a[3] = { 0, 1, 2 };
    make3(a, 3);
    for (int i = 0; i < 3; i++) {
        cout << a[i] << endl;
    }
}

If you can’t add that argument, use std::vector:

#include <vector>

void make3(std::vector<int> &a) {
    for (int i = 0; i < a.size(); i++) {a[i] = 3;}
}

int main()
{
    std::vector<int> a{ 0, 1, 2 };
    make3(a);
    for (int i = 0; i < a.size(); i++) {
        cout << a[i] << endl;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

3

Is this normal?

Yes.

In C++, an array will decay to a pointer at any opportunity. C++ inherited this convenience behavior from C.

It makes thinking about arrays as-if they were the same as pointers. But they are not.

In C++ a pointer can point to nothing (nullptr), or point to an object, or point to an array of objects. The pointer is oblivious of whether it points to an object or an array of objects.

(Or be dangling, or be uninitialized, or be some arbitrary value. These should be avoided.)

If not, what am I doing wrong?

You are not using std::vector.

Since, in the comments, you say that you cannot use a std::vector, then you'll need to pass in the length of the array as a std::size_t parameter along with a pointer to the array.

But you also say you cannot pass in the length of the array. So then you will need to use an array reference rather than a pointer.

Also, C++17 has std::size(a) which can be used instead of sizeof(a)/sizeof(a[0]).

#include <cstddef>
#include <iostream>

using std::cout;
using std::size_t;

template <size_t N>
void make3(int(&a)[N]) {
    for (size_t i = 0; i < N; ++i) {
        a[i] = 3;
    }
}

int main() {
    int a[3] = { 0, 1, 2 };
    make3(a);
    int* b = a;

    for (size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i) {
        cout << *(b + i) << "\n";
    }
}

1 Comment

To be a little bit clearer: a properly initialized non-null pointer always points at an object. Sometimes that object is a single entity, and sometimes it's the first element of an array. (it can also point at an element in the middle of an array, but that's less common). +1.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.