Thread: Character arrays in a Structure

  1. #1
    Im a Capricorn vsriharsha's Avatar
    Join Date
    Feb 2002
    Posts
    192

    Question Character arrays in a Structure

    Hello All,
    I am a little confused about a usage that I have seen in "Unix Network Programming" by Richard Stevens. There a structure was declared as follows...

    struct somename
    {
    some variables;
    char msg[1];
    };

    and then he later used the msg variable to accommodate larger strings. I heard this is a common usage (declaring a character array of 1 byte long and using it to store larger strings, but I really am not getting how it is possible? I mean, will that not be over-writing memory that does not belong to this structure? Please guide.

    Regards,
    Harsha.
    Help everyone you can

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    What page? I think you're misunderstanding the code, as you cannot make that array hold more than one byte.

    [edit]
    And while you're at it, read the Announcements, because you've either neglected to use, or have intentionally left out your [code] tags!
    [/edit]


    [edit2]
    Pages 126 - 132.

    This is a system specific implementation here. They are specificly mentioning Message Queues for System V.

    Some implementations allow you to have an array declared as the final element of a structure, of an arbitrary size. (There's an example on the board, posted by Salem, IIRC, if you wish to search for it. I don't, because I don't care enough to.) In this case, if you read page 126, you'll see the following information, which will tell you what's going on:
    Unix Network Programming, W. Richard Stevens, page 126:
    Message Queues

    Some form of message passing between processes is now a part of may modern operating
    systems. Some operating systems restrict the passing of messages such that a proecss can
    only send a message to another specific process. System V has no such restriction. In
    the System V implementation of messages, all messages are stored in the kernel, and
    have an associated message queue identifier. It is this identifier, which we call an msquid,
    that identifies a particular queue of messages. Processes read and write messages to arbi-
    trary queues. There is no requirement that any process be waiting for a message queue to arrive
    on a queue before some other process is allowed to write a message to that queue. This is
    in contrast to both pipes and FIFOs, where it made no sense to have a writer process
    unless a reader process also exists. It is possible for a process to write some messages to
    a queue, then exit, and have the messages read by another process at a later time.
    Every message on a queue has the following attributes:

    * long integer type;
    * length of the data portion of the message (can be zero);
    * data (if the length is greater than zero).
    On page 128, you'll see the following:
    The ptr argument is a pointer to a structure with the following template. (This template
    is defined in <sys/msg.h>)

    Code:
    struct msgbuf {
        long mtype;        /* message type, musg be > 0 */
        char mtext[1];     /* message data */
    };
    The name mtext is a misnomer--the data portion of the message is not restricted to
    text. Any form of data is allowed, binary data or text. The message type must be greater
    than zero, since a message of type zero is used as a special indicator to the msgrcv sys-
    tem call, which we describe later. By template we mean that the prt argument must point
    to a long integer that contains the type, followed by the message itself (if the
    length of the emssage is greater than zero bytes). The kernel does not interpret the con-
    tents of the message at all. If some cooperating processes wanted to exchange messages
    consisting of a short integer followed by an 8-byte character array, they can define their
    own structure:
    Code:
    typedef struct my_mesgbuf {
        long mtype;        /* message type */
        short mshort;      /* start of message data */
        char mchar[8];
    } Message;
    There's where I'll stop quoting. Basicly, the structure is, as the book explains, a placeholder for a message held by the kernel. It's being used by a pointer to the structure, which is read from. I don't see in this illustration any writing to the structure.

    Basicly, it's as it says, a template, so that you can have a pointer to a message the kernel is holding for you, so you can then read it based on however you have your "message" type defined. See the above illustration of how you might build your own custom messages, which will all take the same form as the first, via a pointer to it.
    [/edit2]

    Quzah.
    Last edited by quzah; 07-11-2004 at 02:32 AM.
    Hope is the first step on the road to disappointment.

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    it's really just an outdated way you would use to peg extra 'userdata' onto objects (and used heavily in the Windows API as well). anyway, something like:

    Code:
    #pragma pack(push, 1)
    typedef struct somename {
     int size;
     char dyn[0];
    } some;
    #pragma pack(pop)
    some * makething(int pad);
    void destroy(some ** thing);
    int main(void) {
     int extra = 1024;
     some * thing = makething(extra);
     printf(" Thing Size: %d.\n", thing->size);
     destroy(&thing);
     return 0;
    }
    some * makething(int pad) {
     int size = sizeof(some)+pad; 
     some * s = malloc(size);
     if(s != NULL) {
      s->size = size;
      memset(s->dyn, size-sizeof(some), 0x0);
      } else {
      fprintf(stderr, "- Out of Memory! - Request: %d.\n", size);
      }
     return s;
    }
    void destroy(some ** x) {
     free(*x);
     *x = 0; 
    }


    [edit] there - happy?!![/edit]
    Last edited by Sebastiani; 07-11-2004 at 02:56 AM.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    void destroy(some ** thing);
    int main(void) {
    int extra = 1024;
    some * thing = makething(extra);
    printf(" Thing Size: %d.\n", thing->size);
    destroy(&thing);
    return 0;
    }
    What's the point of using code tags, when you don't indent worth a [censored]?

    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by vsriharsha
    Code:
    struct somename
    {
       some variables;
       char msg[1];
    };
    Search also struct hack.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  6. #6
    Obsessed with C chrismiceli's Avatar
    Join Date
    Jan 2003
    Posts
    501
    Is the struct hack guaranteed to work, or does it only on certain implementations?
    Help populate a c/c++ help irc channel
    server: irc://irc.efnet.net
    channel: #c

  7. #7
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    >Is the struct hack guaranteed to work, or does it only on certain implementations?

    http://www.eskimo.com/~scs/C-faq/q2.6.html
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  8. #8
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Is the struct hack guaranteed to work, or does it only on certain implementations?
    In C89/90, the struct hack isn't guaranteed to work. In C99, the committee blesses its usage for some strange reason, but don't use it unless you're using C99 and you know the rules.
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Manipulating Character arrays in functions.
    By kbro3 in forum C++ Programming
    Replies: 11
    Last Post: 08-16-2008, 02:24 AM
  2. Comparing elements of character pointer arrays
    By axe in forum C Programming
    Replies: 2
    Last Post: 11-14-2007, 12:20 AM
  3. Character Arrays
    By danielakkerman in forum C Programming
    Replies: 5
    Last Post: 05-20-2007, 04:48 AM
  4. UNICODE and GET_STATE
    By Registered in forum C++ Programming
    Replies: 1
    Last Post: 07-15-2002, 03:23 PM
  5. sorting a structure of arrays
    By Unregistered in forum C Programming
    Replies: 7
    Last Post: 03-15-2002, 11:45 AM