Please help me spot the difference

Discussion in 'C Programming' started by Andreas Vinther, Oct 23, 2006.

  1. I have a small piece of code that compiles but does not perform like I
    want it to.

    This code works:
    ----------------

    void *y0;
    void *y1;
    void *y2;
    void *y3;
    void *y4;

    y0 = ssGetOutputPortSignal(S,0);
    y1 = ssGetOutputPortSignal(S,1);
    y2 = ssGetOutputPortSignal(S,2);
    y3 = ssGetOutputPortSignal(S,3);
    y4 = ssGetOutputPortSignal(S,4);


    This code doesn't work:
    -----------------------

    void **y;
    int i = 0;

    *y = malloc(5 * sizeof(void*));

    while (i < 5)
    {
    *(y+i) = ssGetOutputPortSignal(S,i);
    i++;
    }


    I've also tried to use *y and *(y) instead of *(y+i). They all
    compile, but does also violate my segments :]

    Can anyone tell me why i get segmentation violation?
    To me i seems like the code should perform somewhat similar, but I
    regulary mess up when using pointers and pointers-to-pointers.

    I know I have to use free(*y) later on. I also know that I ought to
    check if malloc returns NULL. But neither seems to generate my problem.

    I beg of all of you C gurus out there, please help poor little stupid
    me. I know that some of you hardcore C guys probably lived inside a
    computercabinet since birth and dream dreams in scrolling green symbols,
    which sometimes fork()'s into severel parallel dream-threads.


    Andreas
    Andreas Vinther, Oct 23, 2006
    #1
    1. Advertising

  2. and with y = malloc(5 * sizeof(void*)); ?
    (instead of *y = )


    Andreas Vinther a écrit :
    > I have a small piece of code that compiles but does not perform like I
    > want it to.
    >
    > This code works:
    > ----------------
    >
    > void *y0;
    > void *y1;
    > void *y2;
    > void *y3;
    > void *y4;
    >
    > y0 = ssGetOutputPortSignal(S,0);
    > y1 = ssGetOutputPortSignal(S,1);
    > y2 = ssGetOutputPortSignal(S,2);
    > y3 = ssGetOutputPortSignal(S,3);
    > y4 = ssGetOutputPortSignal(S,4);
    >
    >
    > This code doesn't work:
    > -----------------------
    >
    > void **y;
    > int i = 0;
    >
    > *y = malloc(5 * sizeof(void*));
    >
    > while (i < 5)
    > {
    > *(y+i) = ssGetOutputPortSignal(S,i);
    > i++;
    > }
    >
    >
    > I've also tried to use *y and *(y) instead of *(y+i). They all
    > compile, but does also violate my segments :]
    >
    > Can anyone tell me why i get segmentation violation?
    > To me i seems like the code should perform somewhat similar, but I
    > regulary mess up when using pointers and pointers-to-pointers.
    >
    > I know I have to use free(*y) later on. I also know that I ought to
    > check if malloc returns NULL. But neither seems to generate my problem.
    >
    > I beg of all of you C gurus out there, please help poor little stupid
    > me. I know that some of you hardcore C guys probably lived inside a
    > computercabinet since birth and dream dreams in scrolling green symbols,
    > which sometimes fork()'s into severel parallel dream-threads.
    >
    >
    > Andreas
    Christian MOENNE-LOCCOZ, Oct 23, 2006
    #2
    1. Advertising

  3. Andreas Vinther

    Ico Guest

    Andreas Vinther <> wrote:
    > I have a small piece of code that compiles but does not perform like I
    > want it to.
    >
    > This code doesn't work:
    > -----------------------
    >
    > void **y;
    > int i = 0;
    >
    > *y = malloc(5 * sizeof(void*));


    Think about what you are doing with the result of malloc() here, where
    does it get stored to ?

    > I beg of all of you C gurus out there, please help poor little stupid
    > me. I know that some of you hardcore C guys probably lived inside a
    > computercabinet since birth and dream dreams in scrolling green symbols,
    > which sometimes fork()'s into severel parallel dream-threads.


    No, you won't find these people here; both fork() and threads are not
    part of ansi C. Try again comp.os.unix.programmer.

    --
    :wq
    ^X^Cy^K^X^C^C^C^C
    Ico, Oct 23, 2006
    #3
  4. "Andreas Vinther" <> wrote in message
    news:453cbb42$0$175$...
    >I have a small piece of code that compiles but does not perform like I want
    >it to.
    >
    > This code works:
    > ----------------
    >
    > void *y0;
    > void *y1;
    > void *y2;
    > void *y3;
    > void *y4;
    >
    > y0 = ssGetOutputPortSignal(S,0);
    > y1 = ssGetOutputPortSignal(S,1);
    > y2 = ssGetOutputPortSignal(S,2);
    > y3 = ssGetOutputPortSignal(S,3);
    > y4 = ssGetOutputPortSignal(S,4);
    >
    >
    > This code doesn't work:
    > -----------------------
    >
    > void **y;
    > int i = 0;
    >
    > *y = malloc(5 * sizeof(void*));
    >
    > while (i < 5)
    > {
    > *(y+i) = ssGetOutputPortSignal(S,i);
    > i++;
    > }
    >
    >
    > I've also tried to use *y and *(y) instead of *(y+i). They all
    > compile, but does also violate my segments :]
    >
    > Can anyone tell me why i get segmentation violation?
    > To me i seems like the code should perform somewhat similar, but I
    > regulary mess up when using pointers and pointers-to-pointers.
    >
    > I know I have to use free(*y) later on. I also know that I ought to check
    > if malloc returns NULL. But neither seems to generate my problem.
    >
    > I beg of all of you C gurus out there, please help poor little stupid me.
    > I know that some of you hardcore C guys probably lived inside a
    > computercabinet since birth and dream dreams in scrolling green symbols,
    > which sometimes fork()'s into severel parallel dream-threads.
    >
    >
    > Andreas


    Instead of
    *y = malloc(5 * sizeof(void*));
    try this
    y = (void **)malloc(5 * sizeof(void*));

    I think that the typecast is not really needed in C
    (but is needed in C++) so I've added it anyway.

    Serafeim
    Papastefanos Serafeim, Oct 23, 2006
    #4
  5. Andreas Vinther <> wrote:
    > I have a small piece of code that compiles but does not perform like I
    > want it to.


    > void **y;
    > int i = 0;
    > *y = malloc(5 * sizeof(void*));


    You assign to something 'y' is pointing to, but since 'y' isn't
    initialized things go badly wrong. Moreover, you try to assign to
    a void pointer something that points to a set of 5 void pointers -
    that might give you a hint that something isn't correct here. Make
    that

    y = malloc(5 * sizeof(void*));

    or, even better,

    y = malloc(5 * sizeof *y);

    to be not dependent on what type 'y' actually has.

    > while (i < 5)
    > {
    > *(y+i) = ssGetOutputPortSignal(S,i);


    The "*(y+i)" bit can also be written as "y", both forms are
    identical.

    > i++;
    > }


    > I've also tried to use *y and *(y) instead of *(y+i). They all
    > compile, but does also violate my segments :]


    You probably will get some compiler warnings for these attempts if
    you raise its warning level - if 'y' is a pointer-to-pointer to void,
    then y is of type pointer to void, and thus assigning to *y or
    *(y) (which is the same, the [] binds more tightly than the de-
    reference operator *) would mean you try to assign a value to a void,
    which of course isn't allowed.
    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
    Jens Thoms Toerring, Oct 23, 2006
    #5
  6. Andreas Vinther

    Richard Bos Guest

    "Papastefanos Serafeim" <> wrote:

    > "Andreas Vinther" <> wrote in message
    > > void **y;
    > > int i = 0;
    > >
    > > *y = malloc(5 * sizeof(void*));
    > >
    > > while (i < 5)
    > > {
    > > *(y+i) = ssGetOutputPortSignal(S,i);
    > > i++;
    > > }


    > Instead of
    > *y = malloc(5 * sizeof(void*));
    > try this
    > y = (void **)malloc(5 * sizeof(void*));
    >
    > I think that the typecast is not really needed in C


    The cast is a Bad Thing in C, and shouldn't be there. For example, one
    of the parts of the code Mr. Vinther did not show us is the bit where he
    #includes his standard headers. If he forgot to #include <stdlib.h>,
    that's a significant error which might have an impact on his problem,
    and the compiler should warn him of this if its error level is set high
    enough - but with your cast, it probably never will.

    Richard
    Richard Bos, Oct 23, 2006
    #6
  7. Andreas Vinther

    Andreas Guest

    Jens Thoms Toerring skrev:
    > Andreas Vinther <> wrote:
    >> I have a small piece of code that compiles but does not perform like I
    >> want it to.

    >
    >> void **y;
    >> int i = 0;
    >> *y = malloc(5 * sizeof(void*));

    >
    > You assign to something 'y' is pointing to, but since 'y' isn't
    > initialized things go badly wrong. Moreover, you try to assign to
    > a void pointer something that points to a set of 5 void pointers -


    That is what I want it to do. I want a void pointer that points to 5
    other void pointers.

    Ofcourse...that's it.. Stupid me I haven't initialised it yet. So if I add:
    void *x
    y = &x;
    to my original code it should work.

    I'm not at my own computer right now, but I think that's it.
    I't not beautifull but it I think it'll work.

    I'll try I as soon as I get home... Thanks a lot y'all (especially you Jens)

    ----- snip ------

    > You probably will get some compiler warnings for these attempts if
    > you raise its warning level - if 'y' is a pointer-to-pointer to void,
    > then y is of type pointer to void, and thus assigning to *y or
    > *(y) (which is the same, the [] binds more tightly than the de-
    > reference operator *) would mean you try to assign a value to a void,
    > which of course isn't allowed.


    I'm aware of that... but I intend to typecast my void pointers to other
    pointers... But at this stage in the code I do not yet know what
    datatype the pointer wil point to. An example could be:

    *((double *)y) = double_value; //if it's of type double

    I think that is a legal aproach

    --- snip -----

    I'll let you all know how it went when I get home.


    Andreas Vinther
    Andreas, Oct 23, 2006
    #7
  8. Andreas <> wrote:
    > Jens Thoms Toerring skrev:
    > > Andreas Vinther <> wrote:
    > >> I have a small piece of code that compiles but does not perform like I
    > >> want it to.

    > >
    > >> void **y;
    > >> int i = 0;
    > >> *y = malloc(5 * sizeof(void*));

    > >
    > > You assign to something 'y' is pointing to, but since 'y' isn't
    > > initialized things go badly wrong. Moreover, you try to assign to
    > > a void pointer something that points to a set of 5 void pointers -


    > That is what I want it to do. I want a void pointer that points to 5
    > other void pointers.


    Mmmm, you might think so, but if you really think about it again you may
    find that you don't want that. And you may be misled a bit by the malloc()
    returning a void pointer and the automatic conversion from void pointers
    to any other types of pointers. But you better think about the problem not
    in terms of void pointers etc. but instead of some "real" data type. Let's
    say you want an array of int pointers. Then you would have

    int **x;
    x = malloc(5 * sizeof *x); /* or x = malloc(5 * sizeof(int *)); */

    and probably wouldn't come up with the idea that 'x' should be an int
    pointer but that it must be a pointer-to-pointer to int. I.e. the thing
    on the left hand side of the assignment must be a pointer to what you
    want allocate memory for, so if you want to allocate memory for a set
    of pointers to int you need a pointer-to-pointer to int. And in exactly
    the same way you should go about dealing with void pointers and poin-
    ters-to-pointers to void. While those may look indistinguishable at the
    first glance they are of different type.

    > Ofcourse...that's it.. Stupid me I haven't initialised it yet. So if I add:
    > void *x
    > y = &x;
    > to my original code it should work.


    It might work but all for the wrong reasons;-) If you need memory
    for a set of values (I avoid the word 'array' here, since an array is
    a bit more than just a collection of consecutive values in memory),
    be ints, doubles or pointers, the type of a pointer to this "set" is
    pointer to the type of the elements of this set. So if you want a set
    of void pointers than a pointer to this (what you get from malloc())
    must be of type pointer-to-pointer to void, not just void pointer. And
    hat's why using

    void **y;
    y = malloc(5 * sizeof(void *)); /* or y = malloc(5 * sizeof *y); */

    is the right way (even if it may be a bit hard to see when you insist
    on thinking in terms of void pointers only and not also types).

    Moreover, if you would use

    void *x;
    void **y = &x;
    *y = malloc(5 * sizeof(void *));

    then using 'y' later is going to be real tricky because 'y' won't be
    a pointer-to-pointer to void (as you told in its definition) but a
    pointer-to-pointer-to-pointer to void. If you lie to the compiler and
    want to get away with it you must know very well what you're doing,
    otherwise it will get its revenge;-)

    > > You probably will get some compiler warnings for these attempts if
    > > you raise its warning level - if 'y' is a pointer-to-pointer to void,
    > > then y is of type pointer to void, and thus assigning to *y or
    > > *(y) (which is the same, the [] binds more tightly than the de-
    > > reference operator *) would mean you try to assign a value to a void,
    > > which of course isn't allowed.


    > I'm aware of that... but I intend to typecast my void pointers to other
    > pointers... But at this stage in the code I do not yet know what
    > datatype the pointer wil point to. An example could be:


    > *((double *)y) = double_value; //if it's of type double


    > I think that is a legal aproach


    While in principle it is (but only if 'y' is really a pointer-to-
    pointer to void and not a "triple" pointer) this looks a bit like a
    maintenance nightmare in the making. Why insist on using void pointers
    etc. when you already know the type of what you're going to store?
    Except in special cases I found it to be better for my mental sanity
    (as far as any is left;-) to use the correct types wherever possible
    and not to obfuscate what's happening by the use of "generic" pointers
    and casts. As a rule I try to avoid situations where casts are needed -
    often they just show that one hasn't really understood what's going on
    and instead of thinking clearly is groping in the dark for some
    "solution" that might seems to work (but, alas, often not really does).

    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
    Jens Thoms Toerring, Oct 23, 2006
    #8
  9. On Mon, 2006-10-23 at 16:29 +0300, Papastefanos Serafeim wrote:
    > "Andreas Vinther" <> wrote in message
    > news:453cbb42$0$175$...
    > > This code doesn't work:
    > > -----------------------
    > >
    > > void **y;
    > > int i = 0;
    > >
    > > *y = malloc(5 * sizeof(void*));
    > >
    > > while (i < 5)
    > > {
    > > *(y+i) = ssGetOutputPortSignal(S,i);
    > > i++;
    > > }
    > >
    > > Can anyone tell me why i get segmentation violation?
    > > To me i seems like the code should perform somewhat similar, but I
    > > regulary mess up when using pointers and pointers-to-pointers.
    > >

    >
    > Instead of
    > *y = malloc(5 * sizeof(void*));
    > try this
    > y = (void **)malloc(5 * sizeof(void*));
    >
    > I think that the typecast is not really needed in C
    > (but is needed in C++) so I've added it anyway.


    Absolutely not. This disguises the fact that you may not have #include'd
    <stdlib.h>. (Which, somewhat ironically, may have been the OP's
    problem.)

    --
    Andrew Poelstra <http://www.wpsoftware.net/projects/>
    Andrew Poelstra, Oct 24, 2006
    #9
  10. --- snip ----

    >> I'm aware of that... but I intend to typecast my void pointers to other
    >> pointers... But at this stage in the code I do not yet know what
    >> datatype the pointer wil point to. An example could be:

    >
    >> *((double *)y) = double_value; //if it's of type double

    >
    >> I think that is a legal aproach

    >
    > While in principle it is (but only if 'y' is really a pointer-to-
    > pointer to void and not a "triple" pointer) this looks a bit like a
    > maintenance nightmare in the making. Why insist on using void pointers
    > etc. when you already know the type of what you're going to store?
    > Except in special cases I found it to be better for my mental sanity
    > (as far as any is left;-) to use the correct types wherever possible
    > and not to obfuscate what's happening by the use of "generic" pointers
    > and casts. As a rule I try to avoid situations where casts are needed -
    > often they just show that one hasn't really understood what's going on
    > and instead of thinking clearly is groping in the dark for some
    > "solution" that might seems to work (but, alas, often not really does).


    I see what you mean and I apreciate your help. Like you, I think it's
    always best to use datatype specific pointers. But you wrote that I
    insist on using void pointers when I already know the datatype I'm going
    to point to. That is just it. I do NOT yet know the datatype, as I've
    written almost at the top of the text i left in this post. That's why
    I'm forced to use void pointers or make similar code sections for every
    possible datatype.

    The code snip is from a data-logger. The number of variables and their
    datatype is set in runtime and not yet know when the program is
    compiled. That's why I allocate memory dynamically and use void
    pointers. I need to print the values in real-time, and therefore I can't
    just log a big hunk of raw data without knowing the individual values
    and their sizes in memory.
    In hinesight I should have mentioned this ealier or at least been more
    specific.

    BTW, the code works great now and I thank you all for your help.


    PS: I'm sorry for the late reply, but I've just been 10 days to London
    and the hotel we stayed in, only allowed people to use the internet on
    the hotels computers. The computers were "locked" to a few select tasks
    and were 6£/h. Since I'm still a student on a budget, I found the price
    ridiculous, and didn't want to fumble around the internet looking for a
    www-interface for usenet.
    Andreas Vinther, Nov 6, 2006
    #10
    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. Sathyaish

    Please spot out the cause of this bug

    Sathyaish, Nov 19, 2004, in forum: C Programming
    Replies:
    2
    Views:
    384
    Charlie Gordon
    Nov 24, 2004
  2. Replies:
    5
    Views:
    308
    David Thompson
    May 21, 2007
  3. blingk
    Replies:
    6
    Views:
    537
    Martin Honnen
    Jan 14, 2008
  4. shapper
    Replies:
    2
    Views:
    245
    shapper
    Nov 7, 2008
  5. Replies:
    0
    Views:
    144
Loading...

Share This Page