Compute size of struct

Hello,
i was trying to compute size of struct to loop through le struct later to fetch some specific data.

Consider the following code(available here test struct - Wokwi ESP32, STM32, Arduino Simulator)


struct MyStruct 
{
    const char name[15];
    const uint8_t code;
    const float resolution;
};
  
MyStruct listInfo[] =
{
  {"sen0",      0x01,        1.0},     //0
  {"sen1C",  0xff,    0.01},    //1
  {"sen2",  0xcf,    0.01},  
  {"sen3",  0xaa,    0.01}, 
};

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Hello, ESP32-S2!");
}

void loop() {

  int size = getStrucSize(listInfo);
  Serial.print("size:");
  Serial.println(size);

  delay(500);
 
}

int  getStrucSize(MyStruct * structure)
{
  size_t i ,j ;
  i = sizeof(structure);
  Serial.println("****");
  Serial.println(i);  //return the size of pointer instead of 80
  j = sizeof(structure[0]);
  Serial.println(j);    //return 20 and is OK
  Serial.println("****");

  return i/j;

}

inside getStrucSize, i never get get the right value.
I try to use

  • i = sizeof(*structure); //but i got the same issue.
  • getStrucSize(&listInfo); // this one fails to compile with an type conversion error that i do not quite understand

I finally change the getStrucSize function by passing as and arg the size of the struct array (
int getStrucSize(MyStruct * structure, int sizeOfStruct) ). And it seems this approach is "safer"

But for my knowledge, can someone point the error out ?

thanks.
Gui2

That is what people normally do, i.e. determine the size after it is declared/defined and pass that information to functions, if needed.

sizeof(a_pointer) just gives the size of the pointer, which is rarely interesting.

When you pass an array to a function what is actually passed is a pointer to the array. The pointer will be an int so what sizeof() returns is the size of an int, not the size of the array

may be you read about the auto range based for - then you even dont need the number of elements in a separate variable.

Hello,
i get that,
but why sizeof(*structure) give the size of pointer.
I was thinking deferencing the pointer will give the full size of struct. no ?

since you passing to a pointer, there is no way for the uC to know the size that is being pointed to and will only return the size of the pointer.

this on the other hand works (since the struct have already been initialised):

struct MyStruct 
{
    const char name[15];
    const uint8_t code;
    const float resolution;
};
  
MyStruct listInfo[] =
{
  {"sen0",      0x01,        1.0},     //0
  {"sen1C",  0xff,    0.01},    //1
  {"sen2",  0xcf,    0.01},  
  {"sen3",  0xaa,    0.01}, 
};

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Hello, ESP32-S2!");
}

void loop() {

  size_t i ,j ;
  i = sizeof(listInfo);
  Serial.println("****");
  Serial.println(i);  //return the size of pointer instead of 80
  j = sizeof(listInfo[0]);
  Serial.println(j);    //return 20 and is OK
  Serial.println("****");

  Serial.print(i/j);

  delay(500);
 
}

hope that helps....

That is the classic way of finding the number of elements in an array but won't work when you do the calculation in a function to which the array has been passed as a parameter because what is passed is a pointer to the array rather than the array itself

something like:

struct MyStruct
{
  const char name[15];
  const uint8_t code;
  const float resolution;
};

MyStruct listInfo[] =
{
  {"sen0",   0x01,    1.0},     //0
  {"sen1C",  0xff,    0.01},    //1
  {"sen2",  0xcf,    0.01},
  {"sen3",  0xaa,    0.01},
};

uint8_t name2code (char needle[15]) {
  for (auto &i : listInfo) {
    if (!strcmp(needle, i.name)) return i.code;
  }
  return 0; // not found
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Hello, ESP32-S2!");
  Serial.println(name2code("sen0"), HEX);
  Serial.println(name2code("sen1C"), HEX);
  Serial.println(name2code("sen2"), HEX);
  Serial.println(name2code("sen3"), HEX);
}

void loop() {
}

will find the code to a given name

Hello, ESP32-S2!
1
FF
CF
AA

look this over
output

 0x01   1.00 sen0
 0xff   0.01 sen1C
 0xcf   0.01 sen2
 0xaa   0.01 sen3
struct MyStruct {
    const char name[15];
    const uint8_t code;
    const float resolution;
};

MyStruct listInfo [] = {
    {"sen0",  0x01, 1.0},     //0
    {"sen1C", 0xff, 0.01},    //1
    {"sen2",  0xcf, 0.01},
    {"sen3",  0xaa, 0.01},
};
const int N = sizeof(listInfo) / sizeof(MyStruct);

// -----------------------------------------------------------------------------
void
dump ()
{
    char s [90];
    char t [10];
    for (int n = 0; n < N; n++)  {
        dtostrf (listInfo [n].resolution, 6, 2, t);
        sprintf (s, " 0x%02x %6s %s", listInfo [n].code, t, listInfo [n].name);
        Serial.println (s);
    }
}

void setup()
{
    Serial.begin(115200);

    dump ();
}

void loop() { }

i would have normally used NmyStruct, but that seemed log.

as you know, i prefer short symbol names

It doesn't. It will give you the size of the object pointed to by 'structure'. What it won't do is give you the size of an array of those objects.

don't understand
the number of array elements can be determined from the size of the array / sizeof of a single element

size of X: 28
size of arr: 20 bytes, 10 elements
size of x: 112 bytes, 4 elements
struct X {
    int         i;
    float       f;
    int         arr [10];
    const char *desc;
};

X x [] = {
    { 0, 1.23, { 1, 2, 3 }, "elem0" },
    { 1, 3.14, { 4, 5, 6 }, "elem1" },
    { 2, 10.1, { 9, 8, 7 }, "elem2" },
    { 3, 123., { 5, 3, 7 }, "elem3" },
};

char s [90];

void
setup (void)
{
    Serial.begin (9600);

    sprintf (s, "size of X: %d", sizeof(X));
    Serial.println (s);

    sprintf (s, "size of arr: %d bytes, %d elements",
        sizeof(x [0].arr), sizeof(x [0].arr)/sizeof(x [0].arr [0]));
    Serial.println (s);


    sprintf (s, "size of x: %d bytes, %d elements",
                            sizeof(x),  sizeof(x)/sizeof(X));
    Serial.println (s);
}

void loop (void) { }
1 Like

I was answering in the context of the original question where one uses the C-style method of passing an array to a function. In that case, the array's name decays to a pointer. So once inside the function, sizeof(pointer) will give the size of a pointer on the platform in question and sizeof(*pointer) will give the size of a single object in the array being pointed to . However nothing will give you the number of elements in the array. Again, this is inside the function.

in another thread someone asked about returning a ptr to a (locally) defined array and knowing it's size.

besides that fact the the local array is allocated on the stack i said it's common for the calling function to pass an array along with its size to the function which then populates it, possibly returning the # of elements populated

OK, I was answering the question in this thread which is the other direction (into the function).

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.