Notifications
Clear all

Integer Arrays, sizeof, functions and Pointers

7 Posts
2 Users
9 Likes
498 Views
Sid
 Sid
(@sid)
Estimable Member
Joined: 2 years ago
Posts: 128
Topic starter  

Hi all.

Let me start by mentioning that this problem might not be confined to Arduino (it is C++ code, and I am not that great with this ++ version of C, and I am attempting this the typical C way).

Problem:

I need to calculate the size of an array that I am passing to a function and after this is found, I would be processing the array. The other way round is to pass the number of elements as well, along with the array which works flawlessly. But still, (probably I am complicating things by trying to reinvent the wheel or anything) but this code does not work.

I am trying to pass things via pointers. Probably that again is something that is not supported.

Anyways, here is the code (part of it from the loop() funtion) -

void loop() 
{
int arr[][10]{
{0,2,4,5,7},
{10,15,3,5,1,3,6}
};
printSizeofArray(arr[0]);
printSizeofArray(arr[1]);
}

void printSizeofArray(int *arrBase)
{
int sizeofArray = sizeof(*(arrBase))/sizeof(*(arrBase[0]));
Serial.println(sizeofArray);
for( ; sizeofArray >= 0; sizeofArray--)
{
Serial.println(*arrBase[sizeofArray));
}
}

And here is the Error Codes generated -

In function 'void printSizeofArray(int*)':
testingArrayviaParameters.ino:17:59: error: invalid type argument of unary '*' (have 'int')
int sizeofArray = sizeof(*(arrBase))/sizeof(*(arrBase[0]));
^
testingArrayviaParameters.ino:21:40: error: expected ']' before ')' token
Serial.println(*arrBase[sizeofArray));
^
testingArrayviaParameters.ino:21:40: error: invalid type argument of unary '*' (have 'int')
exit status 1
invalid type argument of unary '*' (have 'int')

Life is exploring and learning


   
Quote
frogandtoad
(@frogandtoad)
Noble Member
Joined: 4 years ago
Posts: 1506
 

@sid

Posted by: @sid

Hi all.

Let me start by mentioning that this problem might not be confined to Arduino (it is C++ code, and I am not that great with this ++ version of C, and I am attempting this the typical C way).

Problem:

I need to calculate the size of an array that I am passing to a function and after this is found, I would be processing the array. The other way round is to pass the number of elements as well, along with the array which works flawlessly. But still, (probably I am complicating things by trying to reinvent the wheel or anything) but this code does not work.

I am trying to pass things via pointers. Probably that again is something that is not supported.

Anyways, here is the code (part of it from the loop() funtion) -

void loop() 
{
int arr[][10]{
{0,2,4,5,7},
{10,15,3,5,1,3,6}
};
printSizeofArray(arr[0]);
printSizeofArray(arr[1]);
}

void printSizeofArray(int *arrBase)
{
int sizeofArray = sizeof(*(arrBase))/sizeof(*(arrBase[0]));
Serial.println(sizeofArray);
for( ; sizeofArray >= 0; sizeofArray--)
{
Serial.println(*arrBase[sizeofArray));
}
}

And here is the Error Codes generated -

In function 'void printSizeofArray(int*)':
testingArrayviaParameters.ino:17:59: error: invalid type argument of unary '*' (have 'int')
int sizeofArray = sizeof(*(arrBase))/sizeof(*(arrBase[0]));
^
testingArrayviaParameters.ino:21:40: error: expected ']' before ')' token
Serial.println(*arrBase[sizeofArray));
^
testingArrayviaParameters.ino:21:40: error: invalid type argument of unary '*' (have 'int')
exit status 1
invalid type argument of unary '*' (have 'int')

Unfortunately, when you pass an array to a function, the array will decay to a pointer, and lose it's size information, so using the sizeof operator will no longer provide the correct details... generally, most people just pass the size as you have noted.

Cheers.


   
Sean451 reacted
ReplyQuote
Sid
 Sid
(@sid)
Estimable Member
Joined: 2 years ago
Posts: 128
Topic starter  
Posted by: @frogandtoad

Unfortunately, when you pass an array to a function, the array will decay to a pointer, and lose it's size information, so using the sizeof operator will no longer provide the correct details... generally, most people just pass the size as you have noted.

Thanks @frogandtoad for this. Not sure precisely, but I read that C++ uses something called references as well (which are not pointers, but can still be used to tweak or make changes in the incoming array). Can these be used in place of those pointers?

Nothing to do with my code or the problem as I am not altering anything in the array passed, but am just curious. Hope you wont mind shedding some lights on to this aspect. No issues if you are occupied. Just my curiosity.

Life is exploring and learning


   
Sean451 reacted
ReplyQuote
frogandtoad
(@frogandtoad)
Noble Member
Joined: 4 years ago
Posts: 1506
 

@sid

Posted by: @sid
Posted by: @frogandtoad

Unfortunately, when you pass an array to a function, the array will decay to a pointer, and lose it's size information, so using the sizeof operator will no longer provide the correct details... generally, most people just pass the size as you have noted.

Thanks @frogandtoad for this. Not sure precisely, but I read that C++ uses something called references as well (which are not pointers, but can still be used to tweak or make changes in the incoming array). Can these be used in place of those pointers?

Nothing to do with my code or the problem as I am not altering anything in the array passed, but am just curious. Hope you wont mind shedding some lights on to this aspect. No issues if you are occupied. Just my curiosity.

Sure, no problem.

Indeed, we can pass an array by reference, by using an ampersand "&", known as the "address of operator" in both C, and C++.

However, there is a caveat to this, in that you need to also specify the exact number of elements in the array, in the parameter list reference, which kind of defeats the purpose of what I think you're looking for?

Here is an example of passing a single dimension array by reference:

void printArrayByReference(int (&array)[7]) { // The size 7 here is MANDATORY!  
   int arraySize = sizeof(array) / sizeof(int);

   for(int index(0); index < arraySize; index++) {
     Serial.print(array[index]); Serial.print(" ");
    }
 }

void setup() {  Serial.begin(9600);  int someArray[] = {0, 2, 4, 5, 7, 9, 10};  printArrayByReference(someArray); }

-- output --
0 2 4 5 7 9 10

We can also use C++ templates (another ball game), but they may be only partially supported by Arduino, if at all 😉

Hope this helps!


   
jker, Sid and Sean451 reacted
ReplyQuote
frogandtoad
(@frogandtoad)
Noble Member
Joined: 4 years ago
Posts: 1506
 
Posted by: @frogandtoad

@sid

Posted by: @sid
Posted by: @frogandtoad

Unfortunately, when you pass an array to a function, the array will decay to a pointer, and lose it's size information, so using the sizeof operator will no longer provide the correct details... generally, most people just pass the size as you have noted.

Thanks @frogandtoad for this. Not sure precisely, but I read that C++ uses something called references as well (which are not pointers, but can still be used to tweak or make changes in the incoming array). Can these be used in place of those pointers?

Nothing to do with my code or the problem as I am not altering anything in the array passed, but am just curious. Hope you wont mind shedding some lights on to this aspect. No issues if you are occupied. Just my curiosity.

Sure, no problem.

Indeed, we can pass an array by reference, by using an ampersand "&", known as the "address of operator" in both C, and C++.

However, there is a caveat to this, in that you need to also specify the exact number of elements in the array, in the parameter list reference, which kind of defeats the purpose of what I think you're looking for?

Here is an example of passing a single dimension array by reference:

void printArrayByReference(int (&array)[7]) { // The size 7 here is MANDATORY!  
   int arraySize = sizeof(array) / sizeof(int);

   for(int index(0); index < arraySize; index++) {
     Serial.print(array[index]); Serial.print(" ");
    }
 }

void setup() {  Serial.begin(9600);  int someArray[] = {0, 2, 4, 5, 7, 9, 10};  printArrayByReference(someArray); }

-- output --
0 2 4 5 7 9 10

We can also use C++ templates (another ball game), but they may be only partially supported by Arduino, if at all 😉

Hope this helps!

As a followup (because I have mentioned templates here and in another post), I thought I'd provide an example.  Now, the Arduino environment does support C++ templates, and although I don't believe it supports them in full, it does support the basics - Here's an example that you can add to your bag of tricks library:

template <typename T, int N>
void processArray(T (&array)[N]) {
  for(int index(0); index < int(sizeof(array) / sizeof(N)); index++) {
    Serial.print(array[index]); Serial.print(" ");
   }
 }
  
void setup() 
 {
  Serial.begin(9600);
  
  int someArray[] = {0, 2, 4, 5, 7, 9, 10};
  processArray(someArray);
 }

-- output --
0 2 4 5 7 9 10

In this scenario, the template is able to deduce the type of object provided, and because of this, you do not have to provide it's size in the function parameter list.

Hope this help's.

[edit] - Forgot to mention that this is a function template, and the main power comes from templates when used to create container classes.

Cheers.


   
Sid and Sean451 reacted
ReplyQuote
Sid
 Sid
(@sid)
Estimable Member
Joined: 2 years ago
Posts: 128
Topic starter  

@frogandtoad

Thanks again mate. And that piece of code (Template) looks awesome.

Never studied C++ - only picked up some of the things in course of time. So this Template thing is something very new to me. But I see the amazing opportunities this opens up - I mean, if we have this, we can use the same piece of code to find the number of elements or even print (as in your example) not only  integer arrays, but I think this would work fine for floats and character (single character ' ') arrays as well. Amazing. No function rewriting or overloading needed, I believe.

Oh, off topic, but how do you manage to bring in the colors on the code? I used the code button and then view source one (both at the top) to paste in my code - which of course is from the Arduino IDE, but it did not have the color coding.

Life is exploring and learning


   
Sean451 reacted
ReplyQuote
frogandtoad
(@frogandtoad)
Noble Member
Joined: 4 years ago
Posts: 1506
 

@sid

Posted by: @sid

@frogandtoad

Thanks again mate. And that piece of code (Template) looks awesome.

Never studied C++ - only picked up some of the things in course of time. So this Template thing is something very new to me. But I see the amazing opportunities this opens up - I mean, if we have this, we can use the same piece of code to find the number of elements or even print (as in your example) not only  integer arrays, but I think this would work fine for floats and character (single character ' ') arrays as well. Amazing. No function rewriting or overloading needed, I believe.

Oh, off topic, but how do you manage to bring in the colors on the code? I used the code button and then view source one (both at the top) to paste in my code - which of course is from the Arduino IDE, but it did not have the color coding.

You're welcome!

In your Arduino IDE, select your code, right click and choose "Copy as HTML".  Then on the top ribbon toolbar of the forum reply post, choose the following button/option:

'{;}'

...and then paste your HTML code at the bottom of the window.

Sometimes I have to backspace and press enter again to get it to work, not sure why that is happening though... you can preview your response before posting to see if syntax highlighting has been properly applied.


   
Sean451 reacted
ReplyQuote