Thread: Confused by accessing a double from this struct

  1. #1
    Registered User
    Join Date
    Jan 2014
    Posts
    5

    Confused by accessing a double from this struct

    Hi all,

    I am parsing a binary data file by casting a buffer to a struct. It seems to work really well apart from this one double which is always being accessed two bytes off, despite being in the correct place.

    Please see:

    Code:
      typedef struct InvoiceRow {
        uint INVOICE_NUMBER;
        ...
        double GROSS;
        ...
        char VAT_NUMBER[31];
      } InvoiceRow;
    If I attempt to print GROSS using printf("%f", row->GROSS) I get 0.0000.

    However, if I change the type of GROSS to char[8] and then use the following code, I am presented with the correct number...

    Code:
      typedef struct example {
          double d;
      } example;
      example *blah = (example*)row->GROSS;
      printf("%f", blah->d);
    Any help would be hugely appreciated as I'm a little confused as to why this is happening.

    Thanks,

    Aaron

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you put this in your program:
    Code:
    printf("%d\n", sizeof(InvoiceRow));
    do you get the number you expect? (More generally, you do not get to determine where fields in a struct are placed; the compiler does.)

  3. #3
    Registered User
    Join Date
    Jan 2014
    Posts
    5
    The size is as expected, and writing the struct back out to a file results in exactly the same data as the file I read from. Kinda weird.

    The value which the double was being set to appeared to be two bytes forward from where I wanted it to be. Reading as a char read from the correct position... I modified the file (just for testing) and inserted two space characters immediately before the double in the binary file, and for some reason the double was read in correctly. Could this be related to the size of the stack frame?

    Perhaps reading in directly to a struct was a bad idea... Any thoughts?

    Thanks

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If the size is expected, yet this is happening, either you're bad at expecting or bad at arithmetic when calculating the offset; without the full struct I can't say which. (EDIT: Should maybe clarify that "bad at" means "not working this time"....)

    Speaking of offsets, there is a thing called offsetof; does offsetof give you what you expect? If so, check the actual file you're reading using a hexdump or similar to see if that matches your expectations as well.
    Last edited by tabstop; 01-04-2014 at 08:37 AM.

  5. #5
    Registered User
    Join Date
    Jan 2014
    Posts
    5
    Hey. offsetof is a pretty useful tip, thanks.

    It has showed me that GROSS is type bytes off where I would have thought it would be. This is especially strange though because changing "double GROSS" to "char GROSS[8]" gives me the correct offset without without changing any of the variables before GROSS.

    Why this is happening I am unsure. sizeof(double) is equal to sizeof(char[8]).

    When it is char[8] the bytes match up to what I see in my hex viewer, when it is double it matches up to what I see in the hex viewer two bytes along.

  6. #6
    Registered User
    Join Date
    Jan 2014
    Posts
    5
    I just read about this Data structure alignment - Wikipedia, the free encyclopedia ... I am assuming it is related?

  7. #7
    Registered User
    Join Date
    Jan 2014
    Posts
    5
    Doing the following fixed the issue:

    Code:
    typedef struct InvoiceRow {
      uint INVOICE_NUMBER;
      ...
      double GROSS __attribute__((packed));
    
      ...
      char VAT_NUMBER[31];
    } InvoiceRow;

  8. #8
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    Yes it's structure element packing. The uint you had is padded by 2 bytes to align the next element on a nice machine-friendly boundary... probably 4 byte chunks. You can try #pragma pack before the struct declaration... or perhaps your compiler has a different way to say that.

    I haven't seen it the way you just solved... I guess it's another compiler-specific tool.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Confused with double pointers
    By torino25 in forum C Programming
    Replies: 1
    Last Post: 11-27-2013, 09:13 PM
  2. struct within a struct, odd behavior accessing variables
    By John Gaden in forum C++ Programming
    Replies: 2
    Last Post: 02-28-2012, 06:19 AM
  3. Accessing a struct.
    By brack in forum C Programming
    Replies: 7
    Last Post: 09-04-2010, 01:00 AM
  4. accessing struct element from another struct
    By creek23 in forum C Programming
    Replies: 10
    Last Post: 06-24-2010, 02:56 AM
  5. Seg fault when accessing double pointer
    By cerr in forum C Programming
    Replies: 14
    Last Post: 12-30-2009, 03:50 PM

Tags for this Thread