void * to struct * casting ..please help!

Discussion in 'C Programming' started by Neha, Nov 30, 2006.

  1. Neha

    Neha Guest

    Hi all


    Its seems bit silly que but pleasee explan me why this error is coming
    ? and what will be the solution if i want void * to be intilaize by
    struct * and this code is puerly in C.

    --
    #include <stdlib.h>
    #include <stdio.h>
    #include <memory.h>


    typedef struct AAA
    {
    unsigned char str;
    }Abbb;

    typedef struct BBB
    {
    Abbb ab;
    }Bbbb;

    int main()
    {
    void *a;
    a= (Bbbb *) malloc(sizeof(Bbbb));
    a->ab.str='c';
    printf("%c",a->ab.str);

    return 0;
    }

    erorr----------
    test.c
    D:\C-C++\test.c(27) : error C2223: left of '->ab' must point to
    struct/union
    D:\C-C++\test.c(29) : error C2223: left of '->ab' must point to
    struct/union

    Thanx in Advance
    Neha
    Neha, Nov 30, 2006
    #1
    1. Advertising

  2. Neha

    Tom St Denis Guest

    Neha wrote:
    > typedef struct AAA
    > {
    > unsigned char str;
    > }Abbb;
    >
    > typedef struct BBB
    > {
    > Abbb ab;
    > }Bbbb;
    >
    > int main()
    > {
    > void *a;
    > a= (Bbbb *) malloc(sizeof(Bbbb));
    > a->ab.str='c';
    > printf("%c",a->ab.str);


    What type is "a"?

    Casting changes the interpretation in an expression, not the data type.
    You could do

    ((Bbbb *)a)->ab.str = 'c'

    See the difference?

    If you wanted a to be a pointer to Bbbb then make it a pointer to Bbbb,
    e.g.

    Bbbb *a;

    Also please don't cast the return value of malloc.

    Tom
    Tom St Denis, Nov 30, 2006
    #2
    1. Advertising

  3. Neha

    Guest

    Neha wrote:

    > #include <stdlib.h>
    > #include <stdio.h>
    > #include <memory.h>
    >
    >
    > typedef struct AAA
    > {
    > unsigned char str;
    > }Abbb;
    >
    > typedef struct BBB
    > {
    > Abbb ab;
    > }Bbbb;
    >
    > int main()
    > {
    > void *a;


    a is a "pointer to void" and cannot be dereferenced.

    > a= (Bbbb *) malloc(sizeof(Bbbb));


    malloc() returned a "pointer to void" which you cast to "pointer to
    Bbbb" and then stored in a "pointer to void". The cast is unnecessary,
    unhelpful and could in some cases hide a bug...


    > a->ab.str='c';


    The compiler complains because a is still a "pointer to void" and still
    cannot be dereferenced. This is not a dynamically typed language, once
    you declare a as "pointer to void" that's what it stays.

    > printf("%c",a->ab.str);


    As before...

    > return 0;
    > }


    It would seem most appropriate to declare a as a pointer to Bbbb
    (horrid names you choose).

    If you really need to use "void *" (why?) then you'll need to cast it
    before using it, like this abomination:-

    ((Bbbb *)a)->ab.str='c';
    printf("%c\n",((Bbbb *)a)->ab.str);
    , Nov 30, 2006
    #3
  4. Neha

    santosh Guest

    Neha wrote:
    > Hi all
    >
    >
    > Its seems bit silly que but pleasee explan me why this error is coming
    > ? and what will be the solution if i want void * to be intilaize by
    > struct * and this code is puerly in C.
    >
    > #include <stdlib.h>
    > #include <stdio.h>


    > #include <memory.h>


    Get rid of this non-standard header. malloc() is declared in stdlib.h.

    > typedef struct AAA
    > {
    > unsigned char str;
    > }Abbb;
    >
    > typedef struct BBB
    > {
    > Abbb ab;
    > }Bbbb;


    Rewrite these as:
    typedef struct {
    unsigned char str;
    } Abbb;

    typedef struct {
    Abbb ab;
    } Bbbb;

    > int main()


    Change to int main(void)

    > {
    > void *a;
    > a= (Bbbb *) malloc(sizeof(Bbbb));


    Don't use the cast here and check the return value of malloc().

    > a->ab.str='c';
    > printf("%c",a->ab.str);


    To deference void pointers you must apply the appropriate cast. So:
    ((Bbbb *)a)->ab.str = 'c';
    or
    (*(Bbbb *)a).ab.str = 'c';

    Similarly:
    printf("%c\n", ((Bbbb *)a)->ab.str);
    or the other form.

    > return 0;
    > }

    <snip>
    santosh, Nov 30, 2006
    #4
  5. Neha

    santosh Guest

    Neha wrote:
    > Hi all
    >
    > Its seems bit silly que but pleasee explan me why this error is coming
    > ? and what will be the solution if i want void * to be intilaize by
    > struct * and this code is puerly in C.


    Not purely standard C or even correct C.

    > #include <stdlib.h>
    > #include <stdio.h>


    > #include <memory.h>


    This is a non-standard header.

    > typedef struct AAA
    > {
    > unsigned char str;
    > }Abbb;
    >
    > typedef struct BBB
    > {
    > Abbb ab;
    > }Bbbb;


    Rewrite these as:
    typedef struct {
    unsigned char str;
    } Abbb;

    typedef struct {
    Abbb ab;
    } Bbbb;

    > int main()


    Use int main(void)

    > {
    > void *a;
    > a= (Bbbb *) malloc(sizeof(Bbbb));


    The cast is not needed here. Moreover check the return value of
    malloc().

    > a->ab.str='c';
    > printf("%c",a->ab.str);


    To deference a void pointer you must cast it to the appropriate type.
    So:
    ((Bbbb *)a)->ab.str = 'c';
    printf("%c\n", ((Bbbb *)a)->ab.str);

    Note: None of the parenthesis are redundant.

    > return 0;
    > }
    santosh, Nov 30, 2006
    #5
  6. Neha wrote:
    > Hi all
    >
    >
    > Its seems bit silly que but pleasee explan me why this error is coming
    > ? and what will be the solution if i want void * to be intilaize by
    > struct * and this code is puerly in C.


    #include <stdlib.h>
    #include <stdio.h>
    #if 0
    /* mha: <memory.h> is not a standard header */
    #include <memory.h>
    #endif

    typedef struct AAA
    {
    unsigned char str;
    } Abbb;

    typedef struct BBB
    {
    Abbb ab;
    } Bbbb;

    int main(void)
    {
    void *a;
    a = malloc(sizeof(Bbbb)); /* mha: removed superfluous cast */
    ((Bbbb *) a)->ab.str = 'c'; /* mha: fixed bogus use of void * here
    and below */
    printf("%c\n", ((Bbbb *) a)->ab.str); /* mha: fixed lack of '\n'
    on last line of output */
    return 0;
    }
    Martin Ambuhl, Nov 30, 2006
    #6
  7. "Tom St Denis" <> writes:
    > Neha wrote:
    >> typedef struct AAA
    >> {
    >> unsigned char str;
    >> }Abbb;
    >>
    >> typedef struct BBB
    >> {
    >> Abbb ab;
    >> }Bbbb;
    >>
    >> int main()
    >> {
    >> void *a;
    >> a= (Bbbb *) malloc(sizeof(Bbbb));
    >> a->ab.str='c';
    >> printf("%c",a->ab.str);

    >
    > What type is "a"?
    >
    > Casting changes the interpretation in an expression, not the data type.

    [snip]

    That's an odd way of putting it.

    A cast is an expression that specifies a conversion. The operand of
    the cast is of some type (void* in this case); the result is of the
    type specified in the cast (Bbbb* in this case). In both cases, we're
    talking about types of expressions, not of objects.

    Assigning a value to an object *never* changes the type of the object;
    it can only change its value. The fact that that value happens to be
    the result of a conversion to some type doesn't change that.

    So let's look at what happens in the assignment statement

    a= (Bbbb *) malloc(sizeof(Bbbb));

    malloc() returns a result of type void*. You convert that result from
    void* to Bbbb*. You then assign the result of the conversion (which
    is of type Bbbb*) to an object of type void*. This is allowed because
    there's an implicit conversion from void* to any pointer-to-object
    type, and vice versa. So the result of malloc() is converted
    explicitly from void* to Bbbb*, and then implicitly back to void*.

    Here's how I'd write it:

    #include <stdio.h>
    #include <stdlib.h>

    struct AAA {
    unsigned char str;
    };

    struct BBB {
    struct AAA ab;
    };

    int main(void)
    {
    struct BBB *a;
    a = malloc(sizeof *a);
    if (a == NULL) {
    fprintf(stderr, "malloc failed\n");
    exit(EXIT_FAILURE);
    }
    a->ab.str = 'c';
    printf("%c\n", a->ab.str);
    return 0;
    }

    --
    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, Nov 30, 2006
    #7
  8. Neha

    Neha Guest

    Hi all


    I am very thank full to all of u to giving me a clear picture of the
    void * and convertion to struct *. :)

    Now i undersatnd what and where is my fault also how to solve it .. !

    Actualy i am just trying this as test exp thats why naming convetion
    are wrong. And specialy i wana use void * bcaz i want to malloc it for
    diffrent diffrent struct * according the condition in my actual code.

    Now i can arrange my code much better way .. !
    Thanx a lot for ur valuable inputs .. !

    Neha

    Keith Thompson wrote:
    > "Tom St Denis" <> writes:
    > > Neha wrote:
    > >> typedef struct AAA
    > >> {
    > >> unsigned char str;
    > >> }Abbb;
    > >>
    > >> typedef struct BBB
    > >> {
    > >> Abbb ab;
    > >> }Bbbb;
    > >>
    > >> int main()
    > >> {
    > >> void *a;
    > >> a= (Bbbb *) malloc(sizeof(Bbbb));
    > >> a->ab.str='c';
    > >> printf("%c",a->ab.str);

    > >
    > > What type is "a"?
    > >
    > > Casting changes the interpretation in an expression, not the data type.

    > [snip]
    >
    > That's an odd way of putting it.
    >
    > A cast is an expression that specifies a conversion. The operand of
    > the cast is of some type (void* in this case); the result is of the
    > type specified in the cast (Bbbb* in this case). In both cases, we're
    > talking about types of expressions, not of objects.
    >
    > Assigning a value to an object *never* changes the type of the object;
    > it can only change its value. The fact that that value happens to be
    > the result of a conversion to some type doesn't change that.
    >
    > So let's look at what happens in the assignment statement
    >
    > a= (Bbbb *) malloc(sizeof(Bbbb));
    >
    > malloc() returns a result of type void*. You convert that result from
    > void* to Bbbb*. You then assign the result of the conversion (which
    > is of type Bbbb*) to an object of type void*. This is allowed because
    > there's an implicit conversion from void* to any pointer-to-object
    > type, and vice versa. So the result of malloc() is converted
    > explicitly from void* to Bbbb*, and then implicitly back to void*.
    >
    > Here's how I'd write it:
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > struct AAA {
    > unsigned char str;
    > };
    >
    > struct BBB {
    > struct AAA ab;
    > };
    >
    > int main(void)
    > {
    > struct BBB *a;
    > a = malloc(sizeof *a);
    > if (a == NULL) {
    > fprintf(stderr, "malloc failed\n");
    > exit(EXIT_FAILURE);
    > }
    > a->ab.str = 'c';
    > printf("%c\n", a->ab.str);
    > return 0;
    > }
    >
    > --
    > 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.
    Neha, Dec 1, 2006
    #8
  9. Neha

    CBFalconer Guest

    Neha wrote:
    >
    > I am very thank full to all of u to giving me a clear picture of the
    > void * and convertion to struct *. :)
    >
    > Now i undersatnd what and where is my fault also how to solve it .. !
    >
    > Actualy i am just trying this as test exp thats why naming convetion
    > are wrong. And specialy i wana use void * bcaz i want to malloc it for
    > diffrent diffrent struct * according the condition in my actual code.
    >
    > Now i can arrange my code much better way .. !
    > Thanx a lot for ur valuable inputs .. !


    Don't top-post. See the links below. Do snip immaterial material
    from your quotes. Don't use confusing childish abbreviations, such
    as 'u', 'bcaz', 'wanna', 'ur'. Spelling counts.

    --
    Some informative links:
    <news:news.announce.newusers
    <http://www.geocities.com/nnqweb/>
    <http://www.catb.org/~esr/faqs/smart-questions.html>
    <http://www.caliburn.nl/topposting.html>
    <http://www.netmeister.org/news/learn2quote.html>
    <http://cfaj.freeshell.org/google/>
    CBFalconer, Dec 1, 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. Ollej Reemt
    Replies:
    7
    Views:
    524
    Jack Klein
    Apr 22, 2005
  2. Stig Brautaset

    `void **' revisited: void *pop(void **root)

    Stig Brautaset, Oct 25, 2003, in forum: C Programming
    Replies:
    15
    Views:
    787
    The Real OS/2 Guy
    Oct 28, 2003
  3. Replies:
    5
    Views:
    825
    S.Tobias
    Jul 22, 2005
  4. Mike
    Replies:
    10
    Views:
    459
    Default User
    Aug 9, 2006
  5. Replies:
    1
    Views:
    405
    Victor Bazarov
    May 23, 2007
Loading...

Share This Page