• 16
• 15
• 12
• 9
• 10

# pass an array? (stock c++)

This topic is 907 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi

I want to make functions to modify general int-arrays of two dimensions such as:

int arr[10][10];

void foo(int * a, int sizeX,int sizeY){

a[2+5*sizeX]=1; //sets (x,y) is (2,5) to (value 1)

}


However this gives me

error C2109: subscript requires array or pointer type

I did something similar before but i cannot remember the syntax.

Thanks for helping out!
Erik

Edited by suliman

##### Share on other sites
Never mind Edited by MarkS

##### Share on other sites
Maybe its too early and I've not had my coffee, or maybe I just haven't needed this kind of syntax in too long (there are better approaches) but I don't see that there should be an error here.

Are you certain there's no typos? Nothing that interferes with the type of 'a'? That the code you have here is exactly the code you're feeding your compiler (copy&paste prefered)?

##### Share on other sites
Unless you have a really good reason to avoid heap allocation, I would always recommend writing a wrapper around a single dimensional std::vector that provides a 2D interface.

Multidimensional array syntax is a nightmare in C and C++.

##### Share on other sites
At any rate, an alternative syntax for array access is *(ARRAY + Y*WIDTH + X), for you that's *(a + 5*SizeX + 2)... Though that's not much help if the compiler still believes that 'a' is anything other than an array of pointer.

While we're here, let me also remind you that the rightmost dimension of an array declaration is your X axis -- that is 'int a[Y][X]' is correct, not the other way around. You might know this, but its a common mistake and it effects exactly the kind of thing you're doing here. Likewise, in 2-dimensional loops, you usually want Y on the outside loop and X on the inside, for the same reasons.

##### Share on other sites
I don't think you can access your two dimensional array like that, because the type decays to "int (*arr)[10]" not int*

That aside, why are you doing it this way? There is almost no reason to use raw arrays in C++ now with std::vector covering dynamically sized arrays and std::array covering compile-time-sized arrays. With those you'll end up with much safer code as they bundle up their sizes and you won't mix up which size is which or accidentally type it in wrong.

If you want to get real fancy, you can use the new array_view type from the new Guideline Support Library which will let you pass various containers to your function without caring about their type. (Despite MS providing the initial implementation it will work on GCC and Clang on Mac and Linux as well) array_view is an early implementation of something the committee is working on standardizing for the next version of C++. Edited by SmkViper

##### Share on other sites
I was able to get it to work in VS 2015 only through type casting.

This compiles:
foo((int *)arr,10,10);


##### Share on other sites

Unless you have a really good reason to avoid heap allocation, I would always recommend writing a wrapper around a single dimensional std::vector that provides a 2D interface.
Multidimensional array syntax is a nightmare in C and C++.

I don't think OP is doing that necessarily. They're looking for a way to pass an array of unknown size to a function. A pointer along with a length or stride is perfectly workable and efficient (though makes the interface prone to mistakes).

BTW, those mistakes are exactly the kind of thing SmkViper noted above that array_view is meant to fix, however I believe array_view only works on a single dimension -- I could be mistaken though. It's probably a good idea to adopt that as a means of passing (segments of) arrays around -- even for a sequential container like vector, array_view is likely better than an iterator pair.

[EDIT] Now that I've had a chance to check, I was indeed mistaken, array_view does indeed support multiple dimensions as SmkViper points out below.

Edited by Ravyne

##### Share on other sites

The safest way to do this in stock C++ is to use a template

template<class T, size_t arraySizeX, size_t arraySizeY>
void function1(T(&array)[arraySizeX][arraySizeY])
{
for (auto counter = 0; counter < arraySizeX; ++counter)
{
for (auto counter1 = 0; counter1 < arraySizeY; ++counter1)
{
array[counter][counter1] = 111;
std::cout << array[counter][counter1] << std::endl;
}
}
}

//Call the function
int anArray[12][3];
function1(anArray);


You can now make use of arraySizeX and arraySizeY inside of the template for the size in both directions. The function syntax looks weird but it will capture the size of the array through the compiler.  You can find more information about this at this link

Caveat though this only works for stuff that is an array, you can't pass a pointer this way, that will actually generate a compile time error.

Edited by NightCreature83