What do you expect the result of sizeof(a) in the following code should be?
struct D
{
char *a;
char *b;
char *c;
};
static struct D a[] =
struct D
{
char *a;
char *b;
char *c;
};
static struct D a[] =
{
{
"1a",
"1b",
"1c"
},
{
"2a",
"2b",
"2c"
}
};
First, you need to know that "sizeof" is a unary (single parameter) operator (not a function):
{
"1a",
"1b",
"1c"
},
{
"2a",
"2b",
"2c"
}
};
First, you need to know that "sizeof" is a unary (single parameter) operator (not a function):
- Usually, the parentheses are used because they're needed as part of a type cast expression, besides, sizeof has a very high precedence, so "sizeof a + b" isn't the same as "sizeof (a+b)". But generally "sizeof a" is perfectly fine.
- “sizeof a++” does not modify a. As the operand of sizeof is not evaluated at runtime.
- sizeof is a compile-time operator that, in order to calculate
the size of an object, requires type information that is only available at
compile-time. You can for example write something like this:
#define N (sizeof a);
int array1[N];
Going
back to our original question, sizeof(a)
will result into 48. If you need the result to be 2, which is the logic answer,
use:
sizeof a / sizeof a[0];
sizeof a / sizeof a[0];
instead
of :
sizeof a;
Another
interesting fact about using sizeof, that
you should take care of the memory padding problems that may make it results
into unexpected results.
For
example, let's consider the following piece of code:
typedef struct struct1
{
UCHAR x;
USHORT y[3];
UCHAR z;
}struct1;
struct1 struct1_instance = {
(UCHAR)0x00,
{(USHORT)0xFFFF,(USHORT) 0xFFFF,(USHORT)0xFFFF},
(UCHAR)13
}
"sizeof(struct1_instance)" will result into 10 (bytes). While you will most probably expect it to return 8 (bytes). This strange result is due to memory padding in aligned machines. The largest dataytype element in the structure is USHORT, which takes two bytes. So, the structure data will be allocated padding for 2 byte alignment. So, the memory will look like this:
{
UCHAR x;
USHORT y[3];
UCHAR z;
}struct1;
struct1 struct1_instance = {
(UCHAR)0x00,
{(USHORT)0xFFFF,(USHORT)
(UCHAR)13
}
"sizeof(struct1_instance)" will result into 10 (bytes). While you will most probably expect it to return 8 (bytes). This strange result is due to memory padding in aligned machines. The largest dataytype element in the structure is USHORT, which takes two bytes. So, the structure data will be allocated padding for 2 byte alignment. So, the memory will look like this:
Bytes
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
9
|
10
|
Member
|
x
|
Padding
|
y[1]
|
y[2]
|
y[3]
|
z
|
padding
|
If you want to
disable the memory padding, you should use "#pragma
pack"; which instructs the compiler to pack structure members with
a particular alignment.
With #pragma pack(1), the struct above would be laid out like this:
With #pragma pack(1), the struct above would be laid out like this:
Bytes
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
Member
|
x
|
y[1]
|
y[2]
|
y[3]
|
z
|
And
sizeof(struct1_instance) would be 8 instead
of 10.
In this case, the code will look like the following:
# pragma pack (1)
typedef struct struct1
{
UCHAR x;
USHORT y[3];
UCHAR z;
}struct1;
# pragma pack ()
In this case, the code will look like the following:
# pragma pack (1)
typedef struct struct1
{
UCHAR x;
USHORT y[3];
UCHAR z;
}struct1;
# pragma pack ()
No comments:
Post a Comment