12-23-04 11:00 PM
<Jens.Toerring@physik.fu-berlin.de> wrote in message news:32vljgF3qu8s3U1@un
i-berlin.de...
: Jaguk Ku <jkku@softeleware.com> wrote:
: > I made a simple test program below
:
: > =======================================
: > #include <stdio.h>
:
: > struct _TEST {
: > char s1[4];
: > char s2[10];
: > } TEST;
:
: > int main()
: > {
: > memset(&TEST, 0x00, sizeof(TEST));
:
: > *(int*)TEST.s2 = 10;
:
: > printf("s2=%d\n", *(int*)TEST.s2);
:
: > exit(0);
: > }
: > =======================================
: > the output is normal like below
: > s2=10
:
: > but when i change struct _TEST little bit like below
:
: > =======================================
: > struct _TEST {
: > char s1[3];
: > char s2[10];
: > } TEST;
: > =======================================
:
: > it suddenly died with core dump when i executed it.
: > I don't know what is wrong.
:
: What you get here is a "bus error" and that is due to an alignment
: problem. You seem to be using a processor that has certain restric-
: tions when accessing multi-byte quantities (like an int) at once -
: they must start on even addresses (or even addresses that start on
: addresses that can be divided by 4 etc). That's because an access
: like
:
: * ( int * ) TEST.s2 = 10;
:
: will be translated to machine code that uses instructions that move
: 2, 4 or 8 bytes (depending on the sizeof(int) on your machine) a
: once, but expect a properly aligned address to work with.
:
: When you have a structure like
:
: > struct _TEST {
: > char s1[4];
: > char s2[10];
: > } TEST;
:
: 's2' is going to be at an address that can be devided by 4, so if
: you try to use 's2' as an int pointer it my still work since, by
: luck, it's at an acceptable address. But when you change the
: structure to
:
: > struct _TEST {
: > char s1[3];
: > char s2[10];
: > } TEST;
:
: 's2' is now at an odd address and trying to treat that as an int
: pointer won't work with your processor (actually, even on CPUs
: where you don't get a bus error with this it will probably still
: be a significantly slower than a well-aligned access).
:
: That's also the reason why the compiler is allowed to insert as
: many "padding" bytes between the elements of a structure. If you
: would change your structure to
:
: > struct _TEST {
: > char s1[3];
: > int s2;
: > } TEST;
:
: and would check the offset of 's2' from the start of the structure
: you will find that it isn't 3 (as one may expect by just counting
: bytes) but 4 to take care of the alignment requirements on your
: machine - to do that the compiler inserts an extra byte between 's1'
: and 's2'. So never assume that sizeof(TEST) is equal to the sum of
: the sizes of its components!
:
: For that reason you should be very careful with casting between
: pointers to different types - they can have different alignment
: requirements, thus using what's really a char pointer as an int
: pointer might get you in lots of trouble. The most evil thing
: is that it might even work on a certain type of CPU but break the
: program when you try to port it to a different architecture. So,
: if you have to assign e.g. the data from an int to what's pointed
: to by a char pointer, always make sure to use memcpy() - that
: guarantees that you won't get problems with alignment requirements.
:
: Finally, just for your information, the use of identifiers starting
: with an underscore is not allowed in normal C programs - identifiers
: starting with a leading underscore are reserved for the implementa-
: tion, i.e. for use by the compiler and system header files etc. In
: your case correcting this isn't a problems since
:
: struct TEST {
: char s1[3];
: char s2[10];
: } TEST;
:
: will also do perfectly well, as will do
:
: struct {
: char s1[3];
: char s2[10];
: } TEST;
If you are going you use a field to hold data that you aceess with two
different data types, you need to use a union. Even so, I feel what
you are trying to do may not be portable.
Dan Mercer
:
: Regards, Jens
: --
: \ Jens Thoms Toerring ___ Jens.Toerring@physik.fu-berlin.de
: \__________________________ http://www.toerring.de
[ Post a follow-up to this message ]
|