0

I have a C++ function that starts as such

void findSolutions(vector<MOVE> & solutions, int board[], int maxPegs){
    int newboard[18];
    copy(begin(board), end(board), begin(newboard));
    ...
    more code
    ...
}

I'm trying to copy the parameter "board" into a temporary int array so I don't directly modify the original board. But in copy(), I get the following error from VSCode

no instance of overloaded function "begin" matches the argument list -- argument types are: (int *)

How do I copy the array that gets passed in from the parameter? Thanks

danielschnoll
  • 3,045
  • 5
  • 23
  • 34

2 Answers2

5

std::copy works in terms of iterators. begin()/end() invoked on a pointer i.e. board will not yield an iterator, instead board being an array which decays to a pointer can be directly used as an iterator. You can simply use std::copy in the following manner.

std::copy(board, board + len, newboard);

I assume len is the length you want to copy and make sure that newboard has the capacity to store len number of elements.

aep
  • 1,583
  • 10
  • 18
1

You cannot do this safely. An array decays to a pointer when passed into a function. You will have no way to ensure that the source array has enough bytes to read (unless the application is trivial and you know what's going on the caller side). If you pass an array as a pointer to the first element, it's your responsibility to pass the length of the array too. Assuming boardLen the number of ints in board you can do the following,

void findSolutions(vector<MOVE> & solutions, int board[], size_t boardLen, int maxPegs){
    int newboard[18];
    memcpy(newboard, board, min(sizeof(newboard), boardLen*sizeof(int));
    ...

memcpy copies one byte at a time, hence the boardLen*sizeof(int).

rranjik
  • 690
  • 9
  • 21
  • 1
    This will work if the caller passes the size of the array **in bytes** which is a little unusual. It's more common to pass the number of elements and for you to do `boardLen * sizeof(int)` when you call `memcpy`. – Blastfurnace Jan 02 '20 at 23:49
  • 1
    @user4581301 Thanks for the input. But, in aep's answer, how do we make sure that the `board` has `len` elements to read ? What happens if board was `nullptr` ? Where do we get `len` from ? – rranjik Jan 02 '20 at 23:49
  • @Blastfurnace thanks for the input. I've changed my answer accordingly. – rranjik Jan 02 '20 at 23:57
  • `len` likely comes from the same place as `boardLen`; both implementations doomed if the caller lies. If board is `NULL`, UB results in both aep's answer and this one. A reference to `std::array` is probably a better choice for `board` as it all-but-eliminates all of the problems. – user4581301 Jan 03 '20 at 01:07
  • I'd be cautious with how `board`'s length exceeding the capacity of `newboard` is addressed. Handling it transparently the way `min(sizeof(newboard), boardLen*sizeof(int)` does might be the way to go, but it could also merely move where the bug will manifest. – user4581301 Jan 03 '20 at 01:12
  • On reread, I think I now see where you are coming from. The function can be misused in pretty much any case. In that respect, it's unsafe. – user4581301 Jan 03 '20 at 01:14
  • @user4581301 Thanks for clarification. I agree that the function can be misused in several ways (and that my answer will break if `board` was `nullptr`). I'm not really comfortable with the raw pointer approach. I just wanted to attempt an answer. Also, I wanted to be sure because aep did not mention that the caller specifies `len`. – rranjik Jan 03 '20 at 01:23
  • 2
    I join in your discomfort. There are much better ways to accomplish this. Pretty much any container and the assignment operator makes this all a non-problem. – user4581301 Jan 03 '20 at 01:31