help with a c problem

  • brum65
  • Born
  • Born
  • brum65
  • Posts: 2

Post 3+ Months Ago

Hi i am new to this forum and would appreciate some help on a test question that i encountered some time ago, i am currently revising my 'C' for an exam and have used past questions as a gauge of what i am light on.
I am honestly baffled by this question though and just need to satify myself that i am not entirly dumb.

the question is: what will th following code print and why??

Code: [ Select ]
int main ()
{
int *fred;
static struct
{
char a;
char b;
char c;
char d;
} jim = {0,0,0,0};

jim.c = 1;
jim.d = 2;

fred = (int *) &jim.a;
printf ("%x\n", *fred);
  1. int main ()
  2. {
  3. int *fred;
  4. static struct
  5. {
  6. char a;
  7. char b;
  8. char c;
  9. char d;
  10. } jim = {0,0,0,0};
  11. jim.c = 1;
  12. jim.d = 2;
  13. fred = (int *) &jim.a;
  14. printf ("%x\n", *fred);


I can assume from experience that the issue is with the cast- but do not know why, but the print out is:2010000.
can anyone help me with this puzzle please as it is really doing my head in.
regards in advance
brum
Moderator Remark: added [code] tags
  • Anonymous
  • Bot
  • No Avatar
  • Posts: ?
  • Loc: Ozzuland
  • Status: Online

Post 3+ Months Ago

  • joebert
  • Fart Bubbles
  • Genius
  • User avatar
  • Posts: 13503
  • Loc: Florida

Post 3+ Months Ago

My answer would be along the lines of

"It would print *** and it does so because that's what the format argument for printf says it will print."

but my C skills are lacking so I'm not sure if it's a trick question and it wouldn't even compile because of an asignment error in that last "fred =" line or something. :)
  • spork
  • Brewmaster
  • Silver Member
  • User avatar
  • Posts: 6252
  • Loc: Seattle, WA

Post 3+ Months Ago

This is an awesome problem for a C exam. It requires you to really think about how memory is managed in C.

Let's take it a few parts at a time.

Code: [ Select ]
int *fred;

This simply creates an uninitialized int pointer. Most modern compilers represent int with 32-bits (4-bytes). However, this this very compiler specific. It could easily be represented with only 2 bytes as well. This is a minor problem with the example and for the rest of the time, let's just assume that an integer is represented with 4 bytes.

Code: [ Select ]
static struct {
  char a;
  char b;
  char c;
  char d;
} jim = {0,0,0,0};
  1. static struct {
  2.   char a;
  3.   char b;
  4.   char c;
  5.   char d;
  6. } jim = {0,0,0,0};

This declares a struct consisting of four char member variables. Since a char is one byte in memory, the total size of the struct is 4 bytes. A variable jim is declared with this struct and initialized such that all four char's have value 0.

Code: [ Select ]
jim.c = 1;
jim.d = 2;
  1. jim.c = 1;
  2. jim.d = 2;

This simply sets two values in the struct. Our struct in memory now looks like this:
Code: [ Select ]
{0, 0, 1, 2}

and in hexidecimal, it looks like this:
Code: [ Select ]
0x00, 0x00, 0x01, 0x02



Code: [ Select ]
fred = (int *) &jim.a;

Now, since an int is really just 4 bytes strung together, we can cast the struct variable as an integer consisting of those four individual bytes. By casting the first member of the struct to an int pointer and pointing fred at it, you're saying that there is an integer at this location in memory who's first byte is located at fred.a. With me so far?

Now, when we go to access *fred as a regular integer, we're using those bytes as the integer.

But here's the catch: depending on what machine architecture you're working on, it will print something completely different. If you're on an Intel (x86) machine, integers are represented in little-endian byte order, meaning the most significant byte of the integer comes last. On SPARC machines and a few other architectures, integers are represented in big-endian byte order, meaning the most significant byte comes first.

I'm going to assume you're working on an Intel, and so the machine sees your integer as this:
Code: [ Select ]
0x02010000

which, in decimal, is 33619968.

On a SPARC machine, it would see your integer as this:
Code: [ Select ]
0x00000102

which, in decimal, is 258.

Since you're using the %x specifier in printf(), it will spit out the integer in it's hex form, thus 0x02010000.
  • brum65
  • Born
  • Born
  • brum65
  • Posts: 2

Post 3+ Months Ago

yes thank you for your concise answer, it is an awesome question, i understand all your reasoning and it makes complete sense, it has highlighted my lack of reasoning when understanding memory management.
So with thanks to you i can revisit this and take some good/valuable knowledge from it.
thanks again for your time.
brum.

Post Information

  • Total Posts in this topic: 4 posts
  • Users browsing this forum: No registered users and 70 guests
  • You cannot post new topics in this forum
  • You cannot reply to topics in this forum
  • You cannot edit your posts in this forum
  • You cannot delete your posts in this forum
  • You cannot post attachments in this forum
 
 

© 1998-2014. Ozzu® is a registered trademark of Unmelted, LLC.