pointer to flexible array of structures in other structure

Discussion in 'C Programming' started by ulyses, Dec 23, 2005.

  1. ulyses

    ulyses Guest

    I'm trying to put pointer to flexible array of structures in other
    structure. I want to have pointer to array of pixels in screen
    structure. Here is mine code, but I think it isn't quite all right:

    struct pixel
    {
    int x;
    int y;
    int color;
    };

    struct display
    {
    pixel *screen;
    };

    Now I would like to do something like that (to have screen made of 10
    pixels):

    struct display scr;
    scr.screen = (struct pixel*)malloc(10*(sizeof(struct pixel)));
    scr.screen[0].x = 10;

    and it is working, but what is worrying also
    scr.screen[11].x = 10;

    or
    scr.screen[100].x = 10;

    is working. I don't now what is wrong. I'm not sure but I think I'm
    making mistake when defining structures. How should I define flexible
    array of structures in structure? And how should I point it?

    Thanks for help and Merry Xmas,
    John
     
    ulyses, Dec 23, 2005
    #1
    1. Advertising

  2. ulyses wrote:
    >
    > I'm trying to put pointer to flexible array of structures in other
    > structure. I want to have pointer to array of pixels in screen
    > structure. Here is mine code, but I think it isn't quite all right:
    >
    > struct pixel
    > {
    > int x;
    > int y;
    > int color;
    > };
    >
    > struct display
    > {
    > pixel *screen;
    > };
    >
    > Now I would like to do something like that (to have screen made of 10
    > pixels):
    >
    > struct display scr;
    > scr.screen = (struct pixel*)malloc(10*(sizeof(struct pixel)));


    1) Don't cast the return from malloc(), as it only hides the error of
    forgetting the proper header file.

    2) Rather than take sizeof(struct pixel), a "better" solution is to
    use "sizeof(*scr.screen)", as this allows scr.screen to change.

    scr.screen = malloc(10*sizeof(*scr.screen));

    3) Don't forget to check the return for NULL.

    > scr.screen[0].x = 10;
    >
    > and it is working, but what is worrying also
    > scr.screen[11].x = 10;
    >
    > or
    > scr.screen[100].x = 10;
    >
    > is working. I don't now what is wrong. I'm not sure but I think I'm
    > making mistake when defining structures. How should I define flexible
    > array of structures in structure? And how should I point it?


    What's "wrong" is your expectation that C will do the bounds checking
    for you, which it does not. If you need this, then you should store
    the number of pixels allocated:

    struct display
    {
    int numpixel;
    struct pixel *screen;
    };

    After allocating scr.screen, set scr.numpixel to the number of pixels
    allocated. You then need to do your own bounds checking, perhaps
    through a function:

    [Note: Risking public humiliation by posting untested code.]

    pixel *GetPixel(struct display *pdisp, int subscript)
    {
    ASSERT(subscript >= 0 && subscript < pdisp->numpixel);
    return(&pdisp->screen[subscript]);
    }

    Now, if you attempt:

    GetPixel(&scr,100)->x = 10;

    you will get an assertion error.

    --
    +-------------------------+--------------------+-----------------------------+
    | Kenneth J. Brody | www.hvcomputer.com | |
    | kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Dec 23, 2005
    #2
    1. Advertising

  3. ulyses

    ulyses Guest

    I see. Thanks for your help Kenneth. Still one thing is interesting.
    How can scr.screen[100].x = 10 work when the array's size is 10? What
    is more I can get the value using scr.screen[100].x, e.g. for printf.

    Where is this put in the memory, when only 10 'positions' are alocated?
    Is it placed somewhere in memory and for example some other app can
    erease it?
     
    ulyses, Dec 23, 2005
    #3
  4. "ulyses" <> writes:
    > I'm trying to put pointer to flexible array of structures in other
    > structure. I want to have pointer to array of pixels in screen
    > structure. Here is mine code, but I think it isn't quite all right:
    >
    > struct pixel
    > {
    > int x;
    > int y;
    > int color;
    > };
    >
    > struct display
    > {
    > pixel *screen;
    > };


    There's a problem here. You've defined a type called "struct pixel";
    there is no type called "pixel". This should be

    struct pixel *screen;

    <OT>
    In C++ the type "struct pixel" can be referred to as "pixel", but if
    you were programming in C++ you'd have posted to comp.lang.c++,
    wouldn't you?
    </OT>

    > Now I would like to do something like that (to have screen made of 10
    > pixels):
    >
    > struct display scr;
    > scr.screen = (struct pixel*)malloc(10*(sizeof(struct pixel)));
    > scr.screen[0].x = 10;
    >
    > and it is working,


    So far, so good, except that the cast on the malloc() is unnecessary
    and can mask errors such as forgetting to "#include <stdlib.h>" or
    compiling your C code with a C++ compiler. If you get an error
    message without the cast, you need to fix the error, not hide it
    with a cast that says to the compiler, "Shut up, I know what I'm doing".

    The recommended style is

    str.screen = malloc(10 * *scr.screen);

    By not referring to the type "struct pixel" in the malloc() call, you
    don't need to change the call if the type of scr.screen changes later
    on.

    > but what is worrying also
    > scr.screen[11].x = 10;
    >
    > or
    > scr.screen[100].x = 10;
    >
    > is working. I don't now what is wrong. I'm not sure but I think I'm
    > making mistake when defining structures. How should I define flexible
    > array of structures in structure? And how should I point it?


    No, "scr.screen[11].x = 10;" is not "working". It's clobbering memory
    beyond the end of your array, which invokes undefined behavior. That
    means anything can happen, including having it appear to "work".

    C doesn't allow you to index beyond the end of an array object, but it
    doesn't do anything to prevent you from doing so. If you index past
    the end of an array anyway, the compiler isn't obliged to do anything
    about it. It's entirely your responsibility to stay within the bounds
    of your object. This allows better performance when you don't make
    mistakes, at the expense of arbitrarily bad behavior when you do make
    mistakes.

    You should probably have a second member in your "struct display" that
    keeps track of how many pixels you've allocated. For example:

    struct pixel
    {
    int x;
    int y;
    int color;
    };

    struct display
    {
    struct pixel *screen;
    size_t pixel_count;
    };

    struct display scr;
    scr.screen = malloc(10 * sizeof *scr.screen);
    if (scr.screen == NULL) {
    scr.pixel_count = 0; /* malloc failed */
    }
    else {
    scr.pixel_count = 10;
    }


    The allocation and initialization should probably be encapsulated in a
    function that takes the number of pixels as an argument. You might
    want more elaborate error handling as well.

    What you have so far is a decent starting point, but there are a few
    things you should think about as you develop it further.

    I find the use of the terms "screen" and "display" confusing. They
    tend to be nearly synonymous in my mind, but you're not using them
    consistently as far as I can tell. "display" is the name of the
    structure, "screen" is the name of the member of that structure that
    points to the array of pixels, but "scr", an abbreviation of "screen",
    is also the name of an object of type 'struct display". Pick a
    consistent naming scheme now, before your program becomes too
    complicated to go back and fix.

    Also, a screen/display is more than a linear array of pixels. You're
    going to want to keep track of the horizontal and vertical dimensions,
    i.e., you'll need a dynamic 2-dimensional array. Section 6 of the
    comp.lang.c FAQ has some good tips on this.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Dec 23, 2005
    #4
  5. "ulyses" <> writes:
    > I see. Thanks for your help Kenneth. Still one thing is interesting.
    > How can scr.screen[100].x = 10 work when the array's size is 10? What
    > is more I can get the value using scr.screen[100].x, e.g. for printf.


    Please provide context when you post a followup. See
    <http://cfaj.freeshell.org/google/> for instructions on how to do this
    in spite of Google's broken interface.

    Given that scr.screen points to a 10-element array,
    scr.screen[100].x= 10
    doesn't "work". It probably clobbers memory outside the allocated
    bounds of the object, invoking undefined behavior. If it happens that
    the clobbered memory is within your program's address space, and isn't
    currently being used, it can appear to "work". If you're lucky, the
    program will crash when you try to do this. Unfortunately, there are
    no guarantees. It's your job to avoid doing this.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Dec 23, 2005
    #5
  6. ulyses

    ulyses Guest

    Thanks Keith, now everything seems clear. I think that your last post
    solves the whole problem. Thanks to Kenneth also.

    John
     
    ulyses, Dec 24, 2005
    #6
  7. "ulyses" <> writes:
    > Thanks Keith, now everything seems clear. I think that your last post
    > solves the whole problem. Thanks to Kenneth also.


    And again:

    Please provide context when you post a followup. See
    <http://cfaj.freeshell.org/google/> for instructions on how to do this
    in spite of Google's broken interface.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Dec 24, 2005
    #7
  8. On Fri, 23 Dec 2005 23:41:20 GMT, Keith Thompson <>
    wrote:

    > "ulyses" <> writes:


    > > scr.screen = (struct pixel*)malloc(10*(sizeof(struct pixel)));


    > The recommended style is
    >
    > str.screen = malloc(10 * *scr.screen);
    >

    Not quite. (Missing 'sizeof'.)

    <snip rest>

    - David.Thompson1 at worldnet.att.net
     
    Dave Thompson, Jan 4, 2006
    #8
  9. Dave Thompson <> writes:
    > On Fri, 23 Dec 2005 23:41:20 GMT, Keith Thompson <>
    > wrote:
    >
    >> "ulyses" <> writes:

    >
    >> > scr.screen = (struct pixel*)malloc(10*(sizeof(struct pixel)));

    >
    >> The recommended style is
    >>
    >> str.screen = malloc(10 * *scr.screen);
    >>

    > Not quite. (Missing 'sizeof'.)
    >
    > <snip rest>


    Quite right, I don't know how I missed that.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Jan 4, 2006
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Adam Warner

    Flexible array member + variable length array

    Adam Warner, Feb 3, 2005, in forum: C Programming
    Replies:
    10
    Views:
    803
    S.Tobias
    Feb 10, 2005
  2. Alfonso Morra
    Replies:
    11
    Views:
    722
    Emmanuel Delahaye
    Sep 24, 2005
  3. A
    Replies:
    27
    Views:
    1,606
    Jorgen Grahn
    Apr 17, 2011
  4. , India

    pointer to an array vs pointer to pointer

    , India, Sep 20, 2011, in forum: C Programming
    Replies:
    5
    Views:
    458
    James Kuyper
    Sep 23, 2011
  5. valued customer
    Replies:
    10
    Views:
    261
    valued customer
    Feb 25, 2004
Loading...

Share This Page