0

I have initiated an array of 6 elements and tried to print it using a function called 'print'. I have used array object from the stl library. I passed the address of the array object to the print function. When I tried to change the value of the array object in the print function I am getting mismatched types error.

#include <bits/stdc++.h>
using namespace std;
void print(array<int, 6> *arr){
    for(int i : *arr){
        cout<<i<<" ";
    }
    *(*arr+2)=2;
    cout<<endl;
}
int main(){
    array<int, 6> arr2={1, 2, 3, 4, 5, 6};
    print(&arr2);
    print(&arr2);
}

ash54321
  • 133
  • 1
  • 9

4 Answers4

2

In *(*arr+2)=2; you deference the array pointer and try to add 2 to it and then dereference that result to assign 2. I assume you want to assign 2 to the element at index 2 in the array.

You do not need to use pointers here though, take the array by reference.

And, never #include <bits/stdc++.h>.

#include <array>    // include the proper header files
#include <iostream>

void print(std::array<int, 6>& arr) {   // by reference
    for (int i : arr) {
        std::cout << i << ' ';
    }
    arr[2] = 2;        // assign 2 to the element at index 2
    std::cout << '\n'; // std::endl flushes the stream which is usually uncessary
}

int main() {
    std::array<int, 6> arr2 = {1, 2, 3, 4, 5, 6};
    print(arr2);        // and don't take the array address here
    print(arr2);
}

If you really want to use a pointer here, this could be an option:

#include <array>
#include <iostream>

void print(std::array<int, 6>* arr_ptr) {  // pointer
    if (arr_ptr == nullptr) return;        // check that it's pointing at something
    std::array<int, 6>& arr = *arr_ptr;    // dereference it

    for (int i : arr) {
        std::cout << i << ' ';
    }
    arr[2] = 2;
    std::cout << '\n';
}

int main() {
    std::array<int, 6> arr2 = {1, 2, 3, 4, 5, 6};
    print(&arr2);
    print(&arr2);
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • What is the issue in referencing the address from the main function? – ash54321 Jan 04 '22 at 14:30
  • @ash54321 No problem, just totally unecessary. If you send a pointer to the function you often need to check that you don't get a `nullptr` inside the function. By taking it by reference, you don't need to. I added an example to show how that could look. – Ted Lyngmo Jan 04 '22 at 14:38
1

This statement

*(*arr+2)=2;

does not make a sense. For example the operator + is not defined for the class template std::array and as a result this expression *arr+2 is invalid.

You could write

( *arr )[2] = 2;

or for example

*( ( *arr ).begin() + 2 ) = 2;
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1
*(*arr+2)=2;

Would be equivalent to

(*arr)[2] = 2;

if arr were a pointer to an array. I assume that's what you are looking for. But a std::array instance is not an array in that sense. It is an object encapsulating an array, and emulating some of the properties of the underlying array, but it cannot be used interchangeably with the underlying array. In particular, std::array objects do not decay to pointers as actual arrays do, and your code appears to be trying to rely on that.

You could instead do

*((*arr).data() + 2) = 2;

or, more idiomatically,

*(arr->data() + 2) = 2;

to leverage that array-to-pointer decay. Or you could do

arr->data()[2] = 2;

. But none of those is as clear or straightforward as the ...

(*arr)[2] = 2;

... already mentioned, which is what you should do if you must work with a pointer to a std::array instead of a reference to one.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
0

First note that std::array has no operator+. So when you wrote the expression:

*arr+2 // INCORRECT 

In the above expression, you are dereferencing the pointer to std::array and then adding 2 to the result. But as i said at the beginning, that there is no operator+ for std::array, this expression is incorrect.

Limitation

Second you program has a limitation which is that the function print can accept a pointer to an std::array with only 6 elements. So if you try to pass a pointer to an std::array of some different size then your program won't work.

Solution

You can fix these by:

  1. Passing the std::array by reference.
  2. Using templates. In particular, using template nontype parameter.

The advantage of using template nontype parameter is that now you can call the function print with an std::array of different size as shown below.

#include <iostream>
#include <array>

template<std::size_t N> 
void print(std::array<int, N> &arr){ //by reference
    for(const int &i : arr){
        std::cout<<i<<" ";
    }
    arr.at(2) = 2; //use at() member function so that you don't get undefined behavior
    std::cout<<std::endl;
}
int main(){
    std::array<int, 6> arr2={1, 2, 3, 4, 5, 6};
    print(arr2);
    
    std::array<int, 10> arr3 = {1,2,4,3,5,6,7,8,9,10};
    print(arr3);
}

Some of the modifications that i made include:

  1. Removed #include <bits/stdc++.h> and only included headers that are needed.
  2. Used templates. In particular, removed the limitation by using template nontype parameter.
  3. Passed the std::array by reference. That is, there is no need to pass a pointer to an std::array. We can just pass the std::array by reference.
  4. Used at() member function so that we don't go out of bounds and so that we don't get undefined behavior.
Jason
  • 36,170
  • 5
  • 26
  • 60