0

I've got a library function I need to call and I'm having trouble with c++ basics for some reason.

The declaration of the function is:

void doSomething(int** values, int length, int width);

It's taking an array of integer arrays. This is fine, I'm having trouble sending getting the data into it.

My data is just 2 integers, say 4 & 5.

In c# I think the syntax would be somethings like: [ [4,5] ]

An array containing an array which contains the two values. How on earth do you declare this basic structure in C++?

I've tried:

int vals[1][2] = { {4,5} }; doSomething(vals, 1,2);

But the compiler comes back with:

error: no matching function for call to ‘myclass::doSomething(int [1][2], int, int)’ doSomething(vals, 1, 2); ^ src/mysclass.cpp:74:6: note: candidate: void myclass::doSomething(int**, int, int)

This must be simple. There must be a simple way to declare this data to call the function with these values. I'd prefer stack based, if possible.

Jim T
  • 12,336
  • 5
  • 29
  • 43
  • 6
    `int** values` is not an array of arrays. It's an array of `int*` pointers (each of which may or may not point to an `int` array). `int values[][2]` would be an array of arrays (only the leftmost dimension may be omitted). You could do `int vals[1][2] = { {4,5} }; int* ptrs[] = {vals[0]}; doSomething(ptrs, 1, 2);` – Igor Tandetnik Sep 09 '18 at 17:35
  • [No repro](http://coliru.stacked-crooked.com/a/0133aef5c895327f). This example gives a different error message. – πάντα ῥεῖ Sep 09 '18 at 17:37
  • 2
    [This](https://stackoverflow.com/questions/4470950/why-cant-we-use-double-pointer-to-represent-two-dimensional-arrays) is helpful -> 2d arrays don't decay to double pointers – KostasRim Sep 09 '18 at 17:39
  • 3
    See e.g. [this old answer of mine](https://stackoverflow.com/questions/18440205/casting-void-to-2d-array-of-int-c/18440456#18440456) to see why an array of arrays (like `int vals[1][2]`) is *not* like a pointer to pointer (like `int **`). – Some programmer dude Sep 09 '18 at 17:40
  • πάντα ῥεῖ it needs to be a member method to get the exact same error message. The message is right, it's not a compatible data type, I'm just irritated that there's no way to make this definition inline straight out rather than building everything by hand. Igor - yours is roughly what I ended up doing. – Jim T Sep 09 '18 at 17:49
  • I was led astray by a segfault in the library that lead me to think I was getting the input values massively wrong. It's something else. – Jim T Sep 09 '18 at 17:50
  • Similar: `int n[2]; auto p = &n;` (note: it is not `p = n`), type of p is a pointer to an array of length 2: `int (*p)[2] = &n;` - same type of pointer get if your 2D array decays to a pointer. – Aconcagua Sep 09 '18 at 17:50
  • Are the arrays fixed size or not? Answer is very different depending. – Yakk - Adam Nevraumont Sep 09 '18 at 18:12

2 Answers2

1

Parameter int **values denotes a pointer to one pointer (or several consecutive pointers) to one int (or several consecutive ints). The "several consecutive..."-case can be used to represent a "two-dimentional array". Note that values points to an array of pointer values, not to an array of ints. This is different from a data structure like int myArr[10][20], where myArr points to / is an array of arrays of integers.

A simple way to call it is to generate a 1D-array, let an int-pointer point to this array, and pass the address of this pointer:

void test (int** value, int length, int width) {
    for (int l=0; l<length; l++) {
        for (int w=0; w<width; w++) {
            cout << "[" << l << "," << w << "]:" << value[l][w] << endl;
        }
    }
}

int main() {

    int myArr[] = { 4,5 };
    int* ptrToMyArr = myArr;
    test (&ptrToMyArr,1,sizeof(myArr)/sizeof(int));
}
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
1

You could also do something like this:

#include <iostream>

void doSomething(int** value, int length, int width)
{
    for (int i = 0; i < length; ++i)
        for (int j= 0; j < width; ++j)
            std::cout << value[i][j] << std::endl;
}

int main()
{
    // array of arrays of int
    int arr[2][2] = { { 1,2 },{ 3,4 } };

    // convert to array of pointers to int
    int *vals[2] = { arr[0], arr[1] };

    doSomething(vals, 2, 2);

    return 0;
}

https://ideone.com/PgpzK0

Killzone Kid
  • 6,171
  • 3
  • 17
  • 37