3


I'm working on an Arduino project. I'm trying to pass a byte pointer to a function, and let that function calculate the size of the data that the pointer refers to. But when I let the pointer refer to a byte, sizeof() returns 2. I wrote the following snippet to try to debug:

byte b;
byte *byteptr;
byteptr = &b;

print("sizeof(b): ");
println(sizeof(b));

print("sizeof(*byteptr) pointing to byte: ");
println(sizeof(*byteptr));

print("sizeof(byteptr) pointing to byte: ");
println(sizeof(byteptr));

the printed result is:

sizeof(b): 1
sizeof(*byteptr) pointing to byte: 1
sizeof(byteptr) pointing to byte: 2

So the size of a byte is 1, but via the pointer it's 2??

rabensky
  • 2,864
  • 13
  • 18
Maseb
  • 49
  • 2
  • 5

2 Answers2

7

It appears that on Arduino, pointers are 16 bit. I believe your confusion stems from what * means in this context.

sizeof(*byteptr) is equivalent to the sizeof(byte). The * does not indicate a pointer type, it indicates dereferencing the pointer stored in byteptr. Ergo, it is 1 byte, which you would expect from the type byte.

sizeof(byteptr) does not dereference the pointer, and as such, is the size of the pointer itself, which on this system seems to be 2 bytes/16 bits.

Consider the following:

#include "iostream"

using namespace std;

int main()
{
    char a = 1;
    char* aP = &a;

    cout << "sizeof(char): " << sizeof(char) << endl;
    cout << "sizeof(char*): " << sizeof(char*) << endl;
    cout << "sizeof(a): " << sizeof(a) << endl;
    cout << "sizeof(aP): " << sizeof(aP) << endl;
    cout << "sizeof(*aP): " << sizeof(*aP) << endl;
}

Output (on a 64 bit OS/compiler):

sizeof(char): 1
sizeof(char*): 8
sizeof(a): 1
sizeof(aP): 8
sizeof(*aP): 1
  • thanks for the input. But I need to use a pointer to decide the size of the array, if I eg do like tgis byte b[4], byte *byteptr = b, sizeof(*bytptr) still returns 1, any tips? – Maseb Apr 24 '16 at 17:06
  • 1
    @Maseb I suggest asking another question because that is very different from the one you posted. –  Apr 24 '16 at 17:07
  • 1
    @Maseb This might be helpful, though: http://stackoverflow.com/questions/1328223/when-a-function-has-a-specific-size-array-parameter-why-is-it-replaced-with-a-p - getting the size of arrays is an annoying issue in C (or C++ with raw arrays), so personally I'd suggest you just *store* the size and pass it around for the most clarity and lowest chance of errors. –  Apr 24 '16 at 17:09
2

@Maseb I think you've gotten a good discussion of the differences between the size of a dereferenced pointer and the actual size of the pointer itself. I'll just add that the sizeof(byte_pointer) must be large enough so that every address of memory space where a byte value could potentially be stored will fit into the pointer's memory width. For example, if there 32,000 bytes of storage on your Arduino then you could potentially have a pointer that needs to point to the address 32,000. Since 2^15 is about 32,000 you need 14 or 15 bits to create a unique address for each memory storage location. We set pointer address space length to blocks of four bits. Therefore, your Arduino has a 16bit address space for pointers and sizeof(byte_pointer) is 2 bytes, or 16 bits.

With that said, I'll go ahead an answer your other question too. If you need to pass an array and a size, just create your own struct that includes both of those data elements. Then you can pass the pointer to this templated struct which includes the size (This is the basic implementation for the C++ Array container).

I've written the short code sample below to demonstrate how to create your own template for an array with a size element and then use that size element to iterate over the elements.

template<int N>
struct My_Array{
    int size = N;
    int elem[N];
};

//create the pointer to the struct
My_Array<3>* ma3 = new My_Array<3>;

void setup() {
    //now fill the array element
    for(int i=0; i < ma3->size; i++) {
      ma3->elem[0]=i;
    }

    Serial.begin(9600);

    //now you can use the size value to iterate over the elements
    Serial.print("ma3 is this big: ");
    Serial.println(ma3->size);

    Serial.println("The array values are:");
    Serial.print("\t[");
    for(int i=0; i<ma3->size; i++) {
         Serial.print(ma3->elem[i]);
         if(i < ma3->size-1) Serial.print(", ");
    }
    Serial.println("]");
}

void loop() {
    while(true) { /* do nothing */ }
}
ZacSketches
  • 363
  • 2
  • 5
  • 13
  • `int size = N` is a bad idea , that just wastes space in the struct – M.M Apr 25 '16 at 05:35
  • I suppose his original question was about bytes, but how else do your propose to carry the size of the array so he has access to the size and the data via a pointer that can be passed around? – ZacSketches Apr 25 '16 at 16:42
  • It's stored in the type, you don't need an extra variable for it – M.M Apr 25 '16 at 22:46