Thread: Issue with Structs

  1. #16
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Well, as I explained, tx_buffer is a pointer, right?
    Then sizeof(tx_buffer) will return 4 and sizeof(*tx_buffer) won't work because void has no size.
    Strlen, however, is different. It searches the string you pass for '\0' and returns the length it found. In other words, strlen returns the actual length of your string and sizeof returns the actual size of your buffer.
    But remember that sizeof an array returns the total length of the array, but sizeof a pointer returns the size of the pointer or sizeof(*type) gives the size of one element, not the whole buffer/array.

    Strlen is not to be used for finding the length of binary data. It is only guaranteed to work for finding the length of C-style strings.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  2. #17
    Registered User
    Join Date
    Mar 2008
    Posts
    25
    Ok, so presumably:

    tx_buffer will look like this:

    options[0] = 0;
    options[1] = 1;

    [<-12 bytes of header->][<- 2 bytes of options ->][<-10 bytes of message->]

    so what function will get the total length (in this case = 24)?

    Thanks.

  3. #18
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Presumably it is 24 total length, but there's no way you can find out. Strlen does not work on binary data.
    If you used that with strlen, it would return 0, because the first element is '\0' or 0, which marks the end of a C-style string.
    The only way is to keep track of the size yourself.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #19
    Registered User
    Join Date
    Mar 2008
    Posts
    25
    btw, tx_header is a struct - I made a mistake in my prev post.

    corrected to : "DATE tx_header"

    Ok, so I need to pass the size of tx_header to function.

    Shall I just pass: "sizeof(tx_header) + strlen(options) + strlen(message) + 1"

    to the function?

  5. #20
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Sure, that works. The function that creates the buffer also knows the size, so that's fine.
    That's the usual approach, too.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #21
    Registered User
    Join Date
    Mar 2008
    Posts
    25
    Am I right in assuming the "+ 1" is needed because tx_buffer will have a \0 on the end of it?

  7. #22
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    If you copy a string into it, then yes. The length of a string is always strlen(string) + 1 since strlen return the length up unto the '\0' (but does not take into account this char).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #23
    Registered User
    Join Date
    Mar 2008
    Posts
    25
    hmm, do I actually need to do this then:

    void* tx_buffer = malloc(sizeof(tx_header) + strlen(options) + 1 + strlen(message) + 1);

    "sizeof(tx_header) + strlen(options) + 1 + strlen(message) + 1" to get the correct total size?

  9. #24
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    actually - you probably want both options and message nul-terminated - otherwise how you will know on the reciving side where options end and message begins?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  10. #25
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    For all strings, the actual size in memory they take is strlen + 1. But it's usually easier to just split the things and send them one by one. That way you don't have to gut up the data when you receive it at the other end, provided you want to do that, of course.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #26
    Registered User
    Join Date
    Mar 2008
    Posts
    25
    Quote Originally Posted by vart View Post
    actually - you probably want both options and message nul-terminated - otherwise how you will know on the reciving side where options end and message begins?
    that should be fine because in the tx_header, there is a an offset field and a length_of_message field which tell the receiver where everything is.

  12. #27
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by eponymous View Post
    hmm, do I actually need to do this then:

    void* tx_buffer = malloc(sizeof(tx_header) + strlen(options) + 1 + strlen(message) + 1);

    "sizeof(tx_header) + strlen(options) + 1 + strlen(message) + 1" to get the correct total size?
    NO.
    Elysia was wrong to give you the okay on your suggestion that uses strlen. The size of the binary data to send is the size of the buffer you allocated which is:
    Code:
    sizeof(date) + sizeof(options) + sizeof(message));
    No '+1', and No strlen!

    First off strlen should again NOT be used for 'options', and if you were to use strlen for 'message' then you'd have to write an annoying little loop on the receiving end that read characters one at a time until you got a nul char. Not to mention it was just plain wrong as well.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  13. #28
    uint64_t...think positive xuftugulus's Avatar
    Join Date
    Feb 2008
    Location
    Pacem
    Posts
    355
    Fixed size buffers makes life much easier when multiple data structures are to be passed
    using recv/send. The first approach, first posted by Elysia, would be my choice too.
    Code:
    ...
        goto johny_walker_red_label;
    johny_walker_blue_label: exit(-149$);
    johny_walker_red_label : exit( -22$);
    A typical example of ...cheap programming practices.

  14. #29
    Registered User
    Join Date
    Mar 2008
    Posts
    25
    Quote Originally Posted by iMalc View Post
    NO.
    Elysia was wrong to give you the okay on your suggestion that uses strlen. The size of the binary data to send is the size of the buffer you allocated which is:
    Code:
    sizeof(date) + sizeof(options) + sizeof(message));
    No '+1', and No strlen!

    First off strlen should again NOT be used for 'options', and if you were to use strlen for 'message' then you'd have to write an annoying little loop on the receiving end that read characters one at a time until you got a nul char. Not to mention it was just plain wrong as well.
    Code:
    int some_function(char *message) {
    
    DATE tx_header;
    uint8_t options[64]; // this isn't always totally full (normally only the first two elements) so hence the strlen below:
    
    void* tx_buffer = malloc(sizeof(tx_header) + strlen(options) + strlen(message));
    	
    // fill the transmit buffer
    memcpy(tx_buffer, &tx_header, sizeof(tx_header));
    memcpy(tx_buffer + sizeof(tx_header), options, strlen(options));
    memcpy(tx_buffer + sizeof(tx_header) + strlen(options), message, strlen(message));
    	
    printf("strlen(options): &#37;d\n", strlen(options));
    printf("strlen(message): %d\n", strlen(message));
    printf("sizeof(tx_header) is : %d\n", sizeof(tx_header));
    	
    printf("sizeof(tx_buffer) is: %d, strlen(tx_buffer) is: %d\n", sizeof(tx_buffer), strlen(tx_buffer));
    
    }
    If I use sizeof for everything, it's going to return 64 for the options which is larger than what will be sent using the sendto() function. I need to support UP TO 64 options, but not always 64 options. Most of the time, there will be only two options. Options is a string (uint8_t = char if I'm not mistaken).

    The same applies for the message that will be passed in. It can handle up to 300 bytes but will not always be this long. Sizeof(message) is going to return 4 every time as it is getting the size of the pointer.

    Can you please explain some more why you think I should sizeof()?

  15. #30
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by iMalc View Post
    Elysia was wrong to give you the okay on your suggestion that uses strlen. The size of the binary data to send is the size of the buffer you allocated which is:
    Code:
    sizeof(date) + sizeof(options) + sizeof(message));
    No '+1', and No strlen!
    Just to be clear:
    I was mentioning the the length, in bytes, of an ANSI string is strlen(string) + 1. I never did suggest that it was the proper way to do, only that it might work.
    Of course, I had no idea of how the receiving code would use that data.
    And I did suggest splitting it and sending it as 3 parts instead of a whole in the first place.

    And I might also have been somewhat confused, because I wasn't exactly keeping track of the types or how the data was passed to the function. Everyone makes mistakes. Anyway.

    If I use sizeof for everything, it's going to return 64 for the options which is larger than what will be sent using the sendto() function. I need to support UP TO 64 options, but not always 64 options. Most of the time, there will be only two options. Options is a string (uint8_t = char if I'm not mistaken).

    The same applies for the message that will be passed in. It can handle up to 300 bytes but will not always be this long. Sizeof(message) is going to return 4 every time as it is getting the size of the pointer.

    Can you please explain some more why you think I should sizeof()?
    You're making this much harder than you have to. You have a bug in your allocation size too. You actually allocate size for the length of options - 1, but are copying tx_header, which is not a string, into your buffer.
    And, I think, the suggestion to use sizeof is because then you will have fixed-size buffers. That means you can just hack the data to pieces on the other side because you know how big each of the parts of the buffers are.
    Last edited by Elysia; 03-16-2008 at 02:42 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Creating array of structs
    By knirirr in forum C++ Programming
    Replies: 12
    Last Post: 06-18-2008, 08:30 AM
  2. Multidimentional structs + memcpy() == FAIL
    By Viper187 in forum C Programming
    Replies: 8
    Last Post: 06-18-2008, 02:46 AM
  3. float calculation issue
    By George2 in forum C# Programming
    Replies: 1
    Last Post: 05-26-2008, 04:56 AM
  4. ArrayLists + Inner Structs
    By ginoitalo in forum C# Programming
    Replies: 5
    Last Post: 05-09-2002, 05:09 AM
  5. Searching structs...
    By Sebastiani in forum C Programming
    Replies: 1
    Last Post: 08-25-2001, 12:38 PM