Result of 'sizeof' on array of structs in C?
Asked Answered
T

4

38

In C, I have an array of structs defined like:

struct D
{
    char *a;
    char *b;
    char *c;
};

static struct D a[] = {
    {
        "1a",
        "1b",
        "1c"
    },
    {
        "2a",
        "2b",
        "2c"
    }
};

I would like to determine the number of elements in the array, but sizeof(a) returns an incorrect result: 48, not 2. Am I doing something wrong, or is sizeof simply unreliable here? If it matters I'm compiling with GCC 4.4.

Tobe answered 14/12, 2009 at 2:30 Comment(1)
See #1599273 for an answer that includes some hacks to make the techniques posted below safer.Overslaugh
B
48
sizeof a / sizeof a[0];

This is a compile-time constant, so you can use it to, for example, create another array:

#define N sizeof a / sizeof a[0]
int n_a[N];
Butanol answered 14/12, 2009 at 2:31 Comment(5)
In this case, if sizeof(a) is 48, sizeof(a[0]) == 24. That makes each char * take up 8 bytes. sizeof(char *) is probably either 4 or 8, depending on 32-bit/64-bit, but compilers will word align struct members, so each element ends up taking 8 bytes.Peers
Yes, but the nice thing is, the division gives the correct size whether there's padding or not, or whatever be the size of the struct.Butanol
#define should not have a semicolon in the endPyromagnetic
Note, that this might not work if "a" is declared as extern (although it is not the case in the original question). The compiler would not able to determine the sizeof(a) at compile time if it is declared in another source file.Vanish
The macro should be parenthesizedNoles
N
49

sizeof gives you the size in bytes, not the number of elements. As Alok says, to get the number of elements, divide the size in bytes of the array by the size in bytes of one element. The correct C idiom is:

sizeof a / sizeof a[0]
Nephew answered 14/12, 2009 at 2:34 Comment(1)
An alternative, just-as-idiomatic version is sizeof a / sizeof *aCrowfoot
B
48
sizeof a / sizeof a[0];

This is a compile-time constant, so you can use it to, for example, create another array:

#define N sizeof a / sizeof a[0]
int n_a[N];
Butanol answered 14/12, 2009 at 2:31 Comment(5)
In this case, if sizeof(a) is 48, sizeof(a[0]) == 24. That makes each char * take up 8 bytes. sizeof(char *) is probably either 4 or 8, depending on 32-bit/64-bit, but compilers will word align struct members, so each element ends up taking 8 bytes.Peers
Yes, but the nice thing is, the division gives the correct size whether there's padding or not, or whatever be the size of the struct.Butanol
#define should not have a semicolon in the endPyromagnetic
Note, that this might not work if "a" is declared as extern (although it is not the case in the original question). The compiler would not able to determine the sizeof(a) at compile time if it is declared in another source file.Vanish
The macro should be parenthesizedNoles
V
11

sizeof returns the size in memory of the passed element. By dividing the size of an array by a single element size, you get the elements count.

Note that the element size may include some padding bytes as well. For this reason, a padded struct (e.g. when a char member is followed by a pointer) will have a sizeof value greater than it members size sum.

On the other hand, don't let it bother you when counting elements in an array: sizeof(a) / sizeof(a[0]) will still work as smooth as expected.

Voiceful answered 14/12, 2009 at 6:12 Comment(0)
S
-3

ssize_t portfoySayisi = sizeof(*portfoyler);

THIS ONE WORKS

Styrene answered 11/5, 2021 at 20:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.