sizeof an array of structure without using 'sizeof' operator

Hi All,

is it possible to find out the size of an array of structures ( without using 'sizeof' operator). The condition is we have the array of structure instant but we are not aware of the elements inside the structure.

Can someone help me out?

Thanks in advance.

Yes, I guess you can do; something like

#pragma pack(1)
#include <header.h> // Header file which contain opaque structure definition
int main()
{
     char begin;
     struct unknown_structure array[100];
     char end;

     printf("Size of structure = %u ", (&begin > &end) ? (&begin - &end - 1)/100 : (&end - &begin - 1)/100);

     return 0;
}

Let me know the output.
This may not be accurate, refer to alignment and structure padding

I was hoping it should produce a correct number, but that would happen in absence of processors not needing any padding at the end of structures

Not aware of the size of the structure, as in, it contains elements that the compiler has not seen defined?

sizeof doesn't work on those because it really, genuinely doesn't know the size. You can't trick it into giving you information it does not possess; you can't make anything but pointers to those kind of types, and it certainly won't know the size of anything but the pointer.

Otherwise, why not use sizeof? That's what its there for.

Try this -

int main()
{
     struct whatever w;
     char s;

      if( (char*)&w > & z)
        printf("Size of whatever %d\n",(char*)&w-&z)
      else
        printf("Size of whatever %d\n",(char*)&w-&z)
}

Thank you pshaikh. it exactly gives the sizeof the structure. While executing your first sample piece of code... it is mostly &begin is greater than &end. Here all the local variables begin, end and array[100] gets stored in the stack. When you subtract the begin address and end address and divide it by the sizeof the array it gives the sizeof structure.

But if i try to subtract address of say &array[1] - &array[0] doesn't give the sizeof the array instead it gives 1 always. I just tried printing &array[1] and &array[0] which gives the address. When we subtract the address of begin and end variable it gives the number of bytes occupied between those two and why not in &array[1] - &array[0]. Kindly clarify.

Thanks

This is because the compiler has incorrect knowledge about the structure.

Are you casting the array from void * to the right structure type?
Is the structure datatype declared somewhere that you can reference it?

Please post the first few lines of the function that is trying to find the size of the struct.

Because the compiler's doing pointer arithmetic and the difference between 2 succesive pointers is 1. To get the size of any variable that is of that structure type it needs to be cast to an unsigned int...

/* size of any variable of that structure type */
s = (unsigned) &a[1] - (unsigned) &a[0];

/* size of the array will be */
100 * s;

Cast it into an unsigned long instead. unsigned int will truncate a pointer on a lot of architectures.

If you can do array operations on it like that, the compiler knows the size, so sizeof will work.

sizeof(a[0]) * 100

Only on compilers that are strictly 64-bit since they use the LP64 model. Majority of systems in use today are ILP32 so unsigned int is the same as unsigned long but for the sake of portability it should be unsigned long.

Well it was all about determining the size of an array of structures without using sizeof.

This is because, compiler 'knows' type of array and it places instructions of pointer arithmetic using size of 'type'.

so &array[1] - &array[0] = number of elements of type of 'array' between &array[1] and &array[0]

Try this (char*)&array[1] - (char*)&array[0] or (unsigned long)(&array[1]) - (unsigned long)(&array[0])

fine. thank you.

#include <stdio.h>

#pragma pack(1)

main()
{

char begin;
struct ptr
{
int a;
char b;
int *p;
}abc;
char end;

printf("Using sizeof operator = %u\n", sizeof(abc));

printf("Begin address = %u \n",&begin);
printf("end address = %u \n",&end);
printf("first element in struct address = %u \n",&abc.a);
printf("sizeof the structure = %u \n",(&begin > &end) ? (&begin - &end - 1) : (&end - &begin - 1));

}

The sizeof the structure using 'sizeof' operator is 9 as we are using #pragma pack(1)

But if you use the (&begin - &end - 1) logic the size is 15 which is wrong. It is because the
address of end variable is say 1245036
and the address of the first element in the structure is 1245040
and the begin variable address is 1245052.

The first element of the structure is in the address which is a multiple of 4 and within structure we have a 'char' which is not padded and the int * starts immediately after that. but once it comes out of the structure again the 'begin' variable is in multiple of 4. Does it mean #pragma pack(1) packs only the variable inside the structure to avoid structure padding? if it is so then why when we declare

#include <stdio.h>
#pragma pack(1)
struct array
{
int a;
char c;
int d;
int e;
int f;
int h;
};

int main()
{
char begin;
struct array a[100];
char end;
printf("Size of structure = %u ", (&begin > &end) ? (&begin - &end - 1)/100 : (&end - &begin - 1)/100);
}

Here both sizeof operator and the program logic gives the same output 21 which is correct. Am not clear why it is not behaving properly in the below mentioned code. Could someone explain it to me?

main()
{

char begin;
struct ptr
{
int a;
char b;
int *p;
}abc;
char end;

rvan,

Can you try with 'optimization' off in your compiler flags?(whats your OS and machine)

On most platforms, size of word is size of pointer(address) or size of register which can hold address in processor's ALU. (it is sizeof(long))

It is 4 bytes on 32 bit machine, and therefore compiler is aligning your data(variables) at 4 byte boundary or it stores variables at address multiple of 4 (divisible by 4).

This makes processor access data efficiently. Each read operation from main memory, reads a word (4 bytes), so if your data is not aligned, it needs to do more reads than it could with proper alignment

In case of array, it can not pad bytes at the end (so that next variable begins at address divisible by 4); how will it find out next element in array otherwise? Then it has to maintain then size of padding; which may be different for each array variable, as it's addresses may be different; and so whole meaning of efficiency is rendered meaningless.

Try reading on SIGBUS signal and also on structure padding/alignment.

~Thanks

The pragma directive lets you alter the packing of structures but has no affect on ordinary variables. Also it is non-portable and should not be used in code that will be deployed to multiple OSes AIX HPUX Solaris Linux. Output below is from an AIX machine...

#include <stdio.h>

#pragma pack(1)

int main(void)
{
    char beg;
    struct ptr
    {
        int a;
        char b;
        int *p;
    } abc;
    char end;

    printf("Using sizeof operator = %u\n", sizeof(abc));

    printf("beg address = %lu\n", (unsigned long) &beg);
    printf("end address = %lu\n", (unsigned long) &end);
    printf("first element address = %lu\n", (unsigned long) &abc.a);
    printf("last element address = %lu\n", (unsigned long) &abc.p);
    printf("size of structure = %lu\n", (unsigned long) &end - (unsigned long) &abc.a);
}

Output...

using sizeof operator = 9
beg address = 104399808
end address = 104399821
first element address = 104399812
last element address = 104399817
size of structure = 9

Which is a lot of architectures. :slight_smile:

And have been for the last decade, but change is finally happening.

Sure, I suppose... I guess I'm not seeing the point. If you can't do sizeof() on something, you can't measure it with pointer tricks either. Nothing's gained, and legibility is lost.

Ever played trivial pursuit?
:wink: