views:

101

answers:

5

I have following code

#include <stdio.h>
#include<ctype.h>

typedef struct {
  int Type;
  int Type2;
}foo;

typedef struct {
  char cData[40];
}bar;

int main()
{
  bar b1;
  strcpy(b1.cData,"11");
  foo *f=(struct foo *)&b1;
  printf("Type is  %d \n",f->Type);
  return 0;
}

But i am not getting the value of type 1 in f's pointer , instead i am getting size of that particuler struct.

+1  A: 

after the cast

foo* f = (foo*)&b1

you are interpreting the string "11" (which ASCII-wise is represented as 0x31 0x31 binary) and not as the value 11

     +-------------+
f -> | 0x31 | 0x31 |
     +-------------+

not as

     +-------------+
f -> | 0x01 | 0x01 |
     +-------------+

if you wanted to see 11 in type after the cast you would have to do something like

strcpy(b1.cData,"\x001\x001");
Anders K.
It is worse. sizeof(int) is not necessarily sizeof(char) (the latter being always 1), and therefore if the compiler does not optimize the structure, and has 4-byte ints, we will have first int with `0x313100??` (least significant bits random) and second int completely random.
Benoit
+4  A: 

When I run the code (after correcting for errors), it prints 12593. Which is 49*256 + 49 - in other words, "11" as an integer (ascii 1 being 49). So nothing wrong with the code as far as I can see (apart from the memory layout assumptions pointed out by Benoit), so we do need to know what you expected to happen

#include <stdio.h>
#include<ctype.h>

typedef struct {
  int Type;
  int Type2;
}foo;

typedef struct {
  char cData[40];
}bar;

int main()
{
  bar b1;
  foo *f=(foo *)&b1;
  strcpy(b1.cData,"11");
  printf("Type is  %d \n",f->Type);
  return 0;
}
Paul
@paul thanks for such wonderful explanation. I was not getting why number 12593 is been printed. I want to thing such as number 1 will go in type1 and number 2 will go in typ2
anish
"umber 1 will go in type1 and number 2 will go in typ2" -- not sure what you mean there. Edit your question with some example code?
Paul
A: 

After executing your code struct bar looks like this

| 0x31 | 0x31 | 38 * Rubish.... |

casting it to foo makes interpreting this as int. When you print it in hex you will see output similar to this:

printf("Type is  %x \n",f->Type); 
Type is  b7003131 
pejotr
"output similar to this". well, no, since it's the decimal value that will be printed...
Paul
sorry, i've just noticed that. now it's corect :)
pejotr
third byte is filled with zeros :)
Benoit
A: 

Your cast foo *f=(struct foo *)&b1; is wrong, because you have a typedef foo, not a struct foo. Use foo *f=(foo *)&b1; instead. I.e. don't use it at all, because it violates the strict aliasing rule and is undefined behaviour.

You write the data as a string and read it as int, that's the next undefined behaviour.

The strcpy only writes 3 bytes to the struct (two characters and the terminating \0). Assuming 32 bit ints, the fourth byte of the int remains indeterminate. Reading indeterminate values is again undefined behaviour.

Whatever you get as output comes with no surprise, because everything is allowed to happen on undefined behaviour.

Secure
A: 

You are trying to make a pointer to foo (*f) point to another structure 'bar'. foo will not be able to point to this type. Hence you would not be able to cast one structure to the other.

A pointer can point to only data that is used, for the declaration of the pointer.

Try this :

typedef struct {
  int Type;
  int Type2;
}foo;

typedef struct {
  char s[8];
}bar;

int main()
{
  bar b1;
  strcpy(b1.s,"0x01020304");
  foo *f=(struct foo *)&b1;
  printf("Type is  %d \n",f->Type);
  return 0;
}
Roy Samuel