Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

core dump of simple test program
Hi there,

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.

Thanks in advance,

Jaguk Ku



Report this thread to moderator Post Follow-up to this message
Old Post
Jaguk Ku
12-23-04 02:03 PM


Re: core dump of simple test program
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;
>  =======================================[
/color]

> 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;

Regards, Jens
--
\   Jens Thoms Toerring  ___  Jens.Toerring@physik.fu-berlin.de
\__________________________  http://www.toerring.de

Report this thread to moderator Post Follow-up to this message
Old Post
Jens.Toerring@physik.fu-berlin.de
12-23-04 02:03 PM


Re: core dump of simple test program
<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



Report this thread to moderator Post Follow-up to this message
Old Post
Dan Mercer
12-23-04 09:07 PM


Sponsored Links




Last Thread Next Thread Next
Search this forum -> 
Post New Thread

Unix Programming archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 07:58 AM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.