"basic" pointer question

Discussion in 'C Programming' started by Jonathan Bartlett, Jun 27, 2005.

  1. > My questions are these:
    > 1) Do I have to allocate space for the doubles lst_t, lst_vc, lst_ic
    > as well
    > as their pointers?


    I think you are confusing issues. The malloc() statements in your post
    ARE allocating the space for the doubles.

    last_values *lst_ptr = malloc(sizeof(*lst_ptr));

    [however, this should actually be size(last_values)]

    allocates memory for the entire last_values structure, which _includes_
    your three pointers. However, they aren't pointing _to_ anything, yet.

    When you do:

    lst_ptr->lst_t = malloc(sizeof(double));
    lst_ptr->lst_vc = malloc(sizeof(double));
    lst_ptr->lst_ic = malloc(sizeof(double));

    These are allocating space for the _actual double values_, and assigning
    the pointers to theses values to the various members of lst_ptr.

    However, I think, given your goal, you are going about this entirely the
    wrong way. I do not know why you would even need a structure of
    pointers for this, as opposed to just a structure of doubles.

    > 2) Where and how should I define my structure last values assuming
    > that I
    > have no ability to change the related *_h file. i.e. can I just
    > do it at
    > the start of the function I'm creating everything in of do I have
    > to do
    > it at a higher level?


    I have no idea what you are trying to do here. What function are you
    trying to call? What "h" files are you trying to use? It looks like
    some sort of generic callback-with-data interface. Anyway, it would at
    least appear that you are way overusing pointers. Can you make it work
    with just:

    typedef struct {
    double lst_t, lst_vc, lst_ic;
    } last_values;

    That seems to be a much easier plan. You can rid yourself of 3 malloc's
    (and free's!) that way.

    Jon
    ----
    Learn to program using Linux assembly language
    http://www.cafeshops.com/bartlettpublish.8640017
    Jonathan Bartlett, Jun 27, 2005
    #1
    1. Advertising

  2. Jonathan Bartlett

    steve Guest

    I'm trying to create a structure of three pointers to doubles. For
    which I have:

    typedef struct {
    double *lst_t, *lst_vc, *lst_ic;
    } last_values;

    I then need to allocate space for last_values as well as assign the
    value of a pointer to the assigned space. Which I think I'm doing by
    using:

    last_values *lst_ptr = malloc(sizeof(*lst_ptr));

    I then want to associate the pointer *lst_ptr to an existing void
    pointer in another structure that is defined as:

    typedef struct _UserInstDef UserInstDef;
    struct _UserInstDef {
    char *tag;
    void current_mask;
    void *seniorData;
    };

    I do this by using:

    UserInstDef->seniorData = lst_ptr;

    And then I finally allocate space for all of the pointers to doubles
    as:

    lst_ptr->lst_t = malloc(sizeof(double));
    lst_ptr->lst_vc = malloc(sizeof(double));
    lst_ptr->lst_ic = malloc(sizeof(double));

    The goal behind all of this is to be allocating space for 3 double
    values and their pointers and then link those values to an existing
    pionter so I can "smuggle" the values out of a function where I've just
    created them.


    My questions are these:
    1) Do I have to allocate space for the doubles lst_t, lst_vc, lst_ic
    as well
    as their pointers?
    2) Where and how should I define my structure last values assuming
    that I
    have no ability to change the related *_h file. i.e. can I just
    do it at
    the start of the function I'm creating everything in of do I have
    to do
    it at a higher level?
    3) Is there something wrong with the line:
    last_values *lst_ptr = malloc(sizeof(*lst_ptr));
    Am I missing something fundamental here?

    I'm pretty new to C so any help is appreciated.

    Thanks for your time,

    Steve
    steve, Jun 27, 2005
    #2
    1. Advertising

  3. Jonathan Bartlett

    Richard Bos Guest

    "steve" <> wrote:

    > I'm trying to create a structure of three pointers to doubles. For
    > which I have:
    >
    > typedef struct {
    > double *lst_t, *lst_vc, *lst_ic;
    > } last_values;
    >
    > I then need to allocate space for last_values as well as assign the
    > value of a pointer to the assigned space. Which I think I'm doing by
    > using:
    >
    > last_values *lst_ptr = malloc(sizeof(*lst_ptr));
    >
    > I then want to associate the pointer *lst_ptr to an existing void
    > pointer in another structure that is defined as:
    >
    > typedef struct _UserInstDef UserInstDef;
    > struct _UserInstDef {
    > char *tag;
    > void current_mask;
    > void *seniorData;
    > };
    >
    > I do this by using:
    >
    > UserInstDef->seniorData = lst_ptr;
    >
    > And then I finally allocate space for all of the pointers to doubles
    > as:
    >
    > lst_ptr->lst_t = malloc(sizeof(double));
    > lst_ptr->lst_vc = malloc(sizeof(double));
    > lst_ptr->lst_ic = malloc(sizeof(double));
    >
    > The goal behind all of this is to be allocating space for 3 double
    > values and their pointers and then link those values to an existing
    > pionter so I can "smuggle" the values out of a function where I've just
    > created them.
    >
    >
    > My questions are these:
    > 1) Do I have to allocate space for the doubles lst_t, lst_vc, lst_ic
    > as well as their pointers?


    Yes, or find some other way to point them at some valid address - for
    example, by assigning the address of a "normal" double to them.

    > 2) Where and how should I define my structure last values assuming
    > that I have no ability to change the related *_h file. i.e. can I just
    > do it at the start of the function I'm creating everything in of do I have
    > to do it at a higher level?


    That depends mostly on the structure of the program you're writing.

    > 3) Is there something wrong with the line:
    > last_values *lst_ptr = malloc(sizeof(*lst_ptr));
    > Am I missing something fundamental here?


    As long as you have #include <stdlib.h>, nothing.

    Richard
    Richard Bos, Jun 27, 2005
    #3
  4. Jonathan Bartlett

    steve Guest

    For my second question there, is declaring the structure in the
    procedure where I "attach" the structure to the seniorData pointer ok.
    I seem to recall something to do with the structure losing scope when
    the procedure is exited. If that is the case can I just define the
    structure at the top of the *.c file?

    Sorry for the level of the questions but it's been years since I've
    used c and even then it was c++.

    Thanks again for the help.
    steve, Jun 27, 2005
    #4
  5. Jonathan Bartlett

    steve Guest

    Now that you mention it, using three doubles would work just fine. Not
    sure how I came up with the idea for using the pointers.

    So I would create the structure of three doubles and then make
    seniorData point to the new structure. That does seem much easier.

    As for the definition of the structure. The hearder file corresponding
    to my c file is automatically generated by the software using my code
    (long story). i.e. I'm writing file.c and file_h.c I can't change (I
    think calling it the header file is the right term but I could be way
    off). Basically what I'm asking is if I create the structure in a
    function, say pre_analysis, and attach the structure to the one
    variable that is passed to the function that I can mess around with
    will the structure still be there for other functions to use the data
    through userInst->seniorData->lst_* (* in the wildcard sense, not
    pointer sense)?

    Thanks again for the help
    steve, Jun 27, 2005
    #5
  6. Jonathan Bartlett

    Netocrat Guest

    On Mon, 27 Jun 2005 14:26:48 +0000, Richard Bos wrote:

    > "steve" <> wrote:
    >
    >> I'm trying to create a structure of three pointers to doubles. For
    >> which I have:
    >>
    >> typedef struct {
    >> double *lst_t, *lst_vc, *lst_ic;
    >> } last_values;
    >>
    >> I then need to allocate space for last_values as well as assign the
    >> value of a pointer to the assigned space. Which I think I'm doing by
    >> using:
    >>
    >> last_values *lst_ptr = malloc(sizeof(*lst_ptr));
    >>
    >> I then want to associate the pointer *lst_ptr to an existing void
    >> pointer in another structure that is defined as:
    >>
    >> typedef struct _UserInstDef UserInstDef; struct _UserInstDef {
    >> char *tag;
    >> void current_mask;
    >> void *seniorData;
    >> };
    >>
    >> I do this by using:
    >>
    >> UserInstDef->seniorData = lst_ptr;


    What you've written isn't syntactically valid since UserInstDef is a type,
    not a variable. I'm assuming that you're using UserInstDef here to refer
    to a variable of type UserInstDef *, in which case what you've written
    makes sense. If your variable truly is of type UserInstDef, you'd need to
    replace the '->' operator with '.' as in:

    variableOfTypeUserInstDef.seniorData = lst_ptr;

    >> And then I finally allocate space for all of the pointers to doubles
    >> as:
    >>
    >> lst_ptr->lst_t = malloc(sizeof(double)); lst_ptr->lst_vc =
    >> malloc(sizeof(double)); lst_ptr->lst_ic = malloc(sizeof(double));
    >>
    >> The goal behind all of this is to be allocating space for 3 double
    >> values and their pointers and then link those values to an existing
    >> pionter so I can "smuggle" the values out of a function where I've just
    >> created them.


    You may have a valid reason to use pointers to doubles rather than plain
    doubles, but if so you haven't explained it. Is there any reason why you
    can't instead write:

    typedef struct {
    double lst_t, lst_vc, lst_ic;
    } last_values;

    And replace your references to lst_ptr->lst_t with &lst_ptr->lst_t;
    similarly for lst_vc and lst_ic.

    >> My questions are these:
    >> 1) Do I have to allocate space for the doubles lst_t, lst_vc, lst_ic
    >> as well as their pointers?

    >
    > Yes, or find some other way to point them at some valid address - for
    > example, by assigning the address of a "normal" double to them.


    If you use the code I gave above, then there is no need for any
    allocations apart from:

    last_values *lst_ptr = malloc(sizeof(*lst_ptr));

    >> 2) Where and how should I define my structure last values assuming
    >> that I have no ability to change the related *_h file. i.e. can I just
    >> do it at the start of the function I'm creating everything in of do I
    >> have to do it at a higher level?


    I don't see any point in only doing it at the start of the function in
    which you're creating everything since then it will only have scope in
    that function. You won't be able to use variables of that type anywhere
    else. Surely you will need to use it after you have assigned it...

    > That depends mostly on the structure of the program you're writing.
    >
    >> 3) Is there something wrong with the line:
    >> last_values *lst_ptr = malloc(sizeof(*lst_ptr));
    >> Am I missing something fundamental here?

    >
    > As long as you have #include <stdlib.h>, nothing.


    And remember to check whether malloc returned NULL.

    Also to quote your reply post:

    > For my second question there, is declaring the structure in the procedure
    > where I "attach" the structure to the seniorData pointer ok. I seem to
    > recall something to do with the structure losing scope when the procedure
    > is exited. If that is the case can I just define the structure at the
    > top of the *.c file?


    You need to declare the structure so that it is in scope any time you want
    to access a variable of that type (or a pointer to that type). You are
    correct - as I have already explained it does go out of scope when you
    exit that function.

    So it sounds OK to just define it at the top of the *.c file if that's the
    only place you will actually use it.

    In other words, any files where you use UserInstDef but don't access its
    seniorData member as struct *last_values - and don't in any other way
    use a variable of type struct last_values or struct *last_values - don't
    require struct last_values to be in scope. This applies even if you have
    previously assigned a variable of type struct *last_values to the
    seniorData member - the assignment will remain valid even though you can
    only access it as void * and not struct *last_values.
    Netocrat, Jun 27, 2005
    #6
  7. Jonathan Bartlett

    steve Guest

    I wasn't aware of the "->" vs "." difference, that's solved a few
    errors right there.

    As for the double vs. pointer purely an oversight due to lack of
    experience. I think I orignally thought pointers would have a sort of
    global scope. Then I realized that made no sense and never realized
    that using the pointers instead of just doubles makes just about as
    much sense.

    Right now I've got the declaration of the struct at the top of the c
    file and that's the only place it's used so my scope should now be
    fine.

    I haven't forgotten about the NULL checks, but thanks for the reminder.

    All in all the code should pretty much be polished thanks to all your
    help.

    Cheers and thanks again,

    Steve
    steve, Jun 27, 2005
    #7
  8. Jonathan Bartlett, Jun 27, 2005
    #8
  9. Jonathan Bartlett

    CBFalconer Guest

    steve wrote:
    >

    .... snip overly complex solution effort ...
    >
    > The goal behind all of this is to be allocating space for 3 double
    > values and their pointers and then link those values to an existing
    > pionter so I can "smuggle" the values out of a function where I've
    > just created them.


    See what this does for you:

    /* just define a type and give it a name */
    /* a struct label lives in a different namespace */
    /* all the typedef does is avoid retyping struct elsewhere */
    typedef struct smuggled {
    double v1, v2, v3;
    } smuggled;

    smuggled smuggler(/* params as needed */)
    {
    smuggled localvalue;

    /* gyrations */
    localvalue.v1 = firstvalue;
    localvalue.v2 = secondvalue;
    localvalue.v3 = thirdvalue;
    return localvalue;
    }

    void smuguser(....)
    {
    smuggled data;

    ....
    data = smuggler(...);
    fprintf("The product is %f\n", data.v1 * data.v2 * data.v3);
    ....
    }

    many would prefer to replace the word 'smuggled' with "struct
    smuggled" everywhere except in the original typedef, which would
    become a simple struct definition:

    struct smuggled {
    double v1, v2, v3;
    };

    No gyrations with malloc, pointers, etc. are needed. KISS.

    BTW, don't regret having given your solution. We respect people
    who make an effort. The above assumes that I understand your
    objective properly.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    CBFalconer, Jun 27, 2005
    #9
  10. Jonathan Bartlett

    Rajan Guest

    1) Do I have to allocate space for the doubles lst_t, lst_vc, lst_ic
    as well
    as their pointers?
    I think you need not allocate memory for the structure here, you can
    just create an instance by writing.
    last_values l_val;
    But you need to allocate memory for the doubles pointers for that
    structure.
    I find that you have not typecasted the doubles pointers while
    allocating memory , this could give you warnings which can be
    irritating.
    As far as following is concerned, I feel that if you want to assign
    this to void pointer you can do the following
    Moreover UserInstDef is a structure name for which you have'nt created
    an instance of this struct so you have to create UserInstDef
    userInstance;
    userInstance->seniorData = (void *)&l_val;

    2) Where and how should I define my structure last values assuming
    that I
    have no ability to change the related *_h file. i.e. can I just
    do it at
    the start of the function I'm creating everything in of do I have

    to do
    it at a higher level?

    Doing at a higher level is always safer because if you were to use that
    struct instance in a function above the declaration of the structure
    then you won't be able to compile it since the function above does'nt
    know anything about this struct.


    3) Is there something wrong with the line:
    last_values *lst_ptr = malloc(sizeof(*lst_ptr));
    Am I missing something fundamental here?

    There is no reason why you should allocate in the first place. As I
    have written at the top you can just create an instance last_values
    l_val; which should suffice.
    Rajan, Jun 28, 2005
    #10
  11. Jonathan Bartlett

    pete Guest

    Rajan wrote:

    > I find that you have not typecasted the doubles pointers while
    > allocating memory , this could give you warnings which can be
    > irritating.


    No.
    If lack of cast while allocating memory,
    gives you warnings,
    then your code has other problems that you need to know about.

    --
    pete
    pete, Jun 28, 2005
    #11
  12. Jonathan Bartlett

    Rajan Guest

    Pete,
    As we know that malloc() returns a void* , it's always advisable to
    typecast it, otherwise it gives warnings , following is the code and
    then warnings after compilation.

    int main()
    {
    last_values l_val;
    UserInstDef userInstance;
    l_val.lst_t = malloc(sizeof(double));
    l_val.lst_vc = malloc(sizeof(double));
    l_val.lst_ic = malloc(sizeof(double));
    userInstance.seniorData = (void *)&l_val;
    return 0;
    }

    s.c:18: warning: assignment makes pointer from integer without a cast
    s.c:19: warning: assignment makes pointer from integer without a cast
    s.c:20: warning: assignment makes pointer from integer without a cast

    These lines which are displayed are exactly the ones wherein it has
    been malloc'd.

    C compilers are strict about typecasting and they will throw such
    warnings.
    If you don't see these warnings after compilation then probably you
    need to do gcc s.c -Wall to see these warnings.
    It's surprising that you don't get any warnings.
    Rajan, Jun 28, 2005
    #12
  13. Jonathan Bartlett

    Richard Bos Guest

    "Rajan" <> wrote:

    [ I have no idea whom you're replying to. Do learn to post, okay?
    Google's imbecility is not your excuse. ]

    > As we know that malloc() returns a void* , it's always advisable to
    > typecast it,


    Precisely _because_ malloc() returns void *, does it not need, indeed
    should it not get, a cast. void * was created purposely as a generic
    object pointer, to avoid unnecessary casts. Otherwise, what would be the
    use of a void *? We might as well use char *s.

    > otherwise it gives warnings ,


    Not if you're compiling correct C, it doesn't.

    > int main()
    > {
    > last_values l_val;
    > UserInstDef userInstance;
    > l_val.lst_t = malloc(sizeof(double));


    You invoke undefined behaviour here. Adding a cast will only mask the
    problem, which is _not_ that you're assigning a void * somewhere.

    The real problem is that you do not have a declaration for malloc() in
    scope. This means that your compiler is forced to assume that it returns
    an int, which is not correct; this means that trying to read that
    non-existent int causes undefined behaviour: any result may follow.

    The solution is not shutting up the valid warning from the compiler,
    using a cast, but to get rid of the error by adding the declaration for
    malloc(). The most expedient means for this is to #include <stdlib.h>

    If that doesn't stop the warning _and_ get rid of the underlying
    problem, you're not compiling C. Probably, you're using some bastard of
    C and C++.

    Richard
    Richard Bos, Jun 28, 2005
    #13
  14. Rajan wrote:
    > Pete,
    > As we know that malloc() returns a void* ,


    True...

    > it's always advisable to
    > typecast it,


    False. We know no such thing. In fact, anyone who "knows" such a thing
    probably "knows" all manner of other untrue things.

    > otherwise it gives warnings ,


    No C compiler is required to issue a diagnostic. Of course C compilers
    _may_ issue spurious warnings like
    "Warning: You have used 'green' as a variable name. I don't like
    that."
    But you should recognize such warnings as bogus.
    Most likely you are using a C++ compiler if you get such warnings. If
    you use a C++ compiler, you should be writing in the programming
    language C++ and posting to comp.lang.c++. If you want to write C and
    post to comp.lang.c, then learn that your claim is false.

    > following is the code and
    > then warnings after compilation.


    Your warnings,

    > s.c:18: warning: assignment makes pointer from integer without a cast
    > s.c:19: warning: assignment makes pointer from integer without a cast
    > s.c:20: warning: assignment makes pointer from integer without a cast


    come from you error in #including <stdlib.h>. Because you write
    incorrect code and don't know it, you misdiagnose your problem and then
    claim to "know" things that are patently false.

    > C compilers are strict about typecasting and they will throw such
    > warnings.
    > If you don't see these warnings after compilation then probably you
    > need to do gcc s.c -Wall to see these warnings.


    I have almost every possible warning enabled -- many more and including
    all those from 'gcc -Wall' -- and never see such messages. Why? Because
    I don't make your beginner's error.

    > It's surprising that you don't get any warnings.


    It's surprising you pass off your ignorance for wisdom.
    Martin Ambuhl, Jun 28, 2005
    #14
  15. Jonathan Bartlett

    CBFalconer Guest

    Rajan wrote:
    >
    > As we know that malloc() returns a void* , it's always advisable
    > to typecast it, otherwise it gives warnings , following is the
    > code and then warnings after compilation.


    Extremely BAD advice. Others have explained why. DON'T CAST MALLOC.

    --
    "A man who is right every time is not likely to do very much."
    -- Francis Crick, co-discover of DNA
    "There is nothing more amazing than stupidity in action."
    -- Thomas Matthews
    CBFalconer, Jun 28, 2005
    #15
  16. Jonathan Bartlett

    Flash Gordon Guest

    Rajan wrote:
    > Pete,
    > As we know that malloc() returns a void* , it's always advisable to
    > typecast it, otherwise it gives warnings ,


    In which case YOU are doing something wrong.

    > following is the code and
    > then warnings after compilation.
    >
    > int main()
    > {
    > last_values l_val;
    > UserInstDef userInstance;
    > l_val.lst_t = malloc(sizeof(double));
    > l_val.lst_vc = malloc(sizeof(double));
    > l_val.lst_ic = malloc(sizeof(double));
    > userInstance.seniorData = (void *)&l_val;
    > return 0;
    > }
    >
    > s.c:18: warning: assignment makes pointer from integer without a cast
    > s.c:19: warning: assignment makes pointer from integer without a cast
    > s.c:20: warning: assignment makes pointer from integer without a cast
    >
    > These lines which are displayed are exactly the ones wherein it has
    > been malloc'd.
    >
    > C compilers are strict about typecasting and they will throw such
    > warnings.


    Not with void* pointers they are not, and malloc returns void*. Try
    reading the warnings you got. The bit about converting from INTEGER.

    > If you don't see these warnings after compilation then probably you
    > need to do gcc s.c -Wall to see these warnings.
    > It's surprising that you don't get any warnings.


    No, Pete does not see the warnings because he has a prototype for malloc
    in scope. This is conventionally done by including stdlib.h

    Try compiling:

    /* Beginning of source file */
    #include <stdlib.h>
    int main(void)
    {
    int *ptr = malloc(sizeof *ptr);
    free(ptr);
    return 0;
    }
    /* End of source code */

    I also suggest gcc -ansi -pedantic -Wall s.c
    --
    Flash Gordon
    Living in interesting times.
    Although my email address says spam, it is real and I read it.
    Flash Gordon, Jun 28, 2005
    #16
  17. Jonathan Bartlett

    pete Guest

    Rajan wrote:
    >
    > Pete,
    > As we know that malloc() returns a void* , it's


    > always


    Never.

    > advisable to typecast it,


    ITYM cast. Typecasting is something that happens to thespians.

    > l_val.lst_ic = malloc(sizeof(double));


    > s.c:20: warning: assignment makes pointer from integer without a cast



    You neglected to #include <stdlib.h>.

    That's what the warning is telling you.

    Consider:
    warning: assignment makes pointer from integer without a cast

    Integer? What integer? There's no integer there.
    In C89 when you neglect to include the prototype
    prior to a function call,
    the compiler assumes that it returns type int.

    --
    pete
    pete, Jun 28, 2005
    #17
  18. Jonathan Bartlett

    Rajan Guest

    Well, thanks for the advice.Will follow that. I have always come across
    application which are always been typecasted and probably yes they may
    not have included <stdlib.h>
    Rajan, Jun 29, 2005
    #18
  19. Jonathan Bartlett

    Guest

    Rajan wrote:
    > Well, thanks for the advice.Will follow that. I have always come across
    > application which are always been typecasted and probably yes they may
    > not have included <stdlib.h>


    Before C89, the void* type didn't exist; malloc() and calloc() returned
    char*, so a cast *was* necessary if you were assigning the result to a
    different pointer type. Since C89, malloc() and calloc() return void*,
    which does not require a cast[1]. What you saw was either old code, or
    code written by an old C programmer.

    1. Note that this is not the case in C++, but if you're writing C++,
    you should be using new instead of malloc() anyway.
    , Jun 30, 2005
    #19
    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. Replies:
    10
    Views:
    673
    Chris Torek
    Feb 4, 2005
  2. jimjim
    Replies:
    16
    Views:
    822
    Jordan Abel
    Mar 28, 2006
  3. Replies:
    4
    Views:
    1,230
    Fred Zwarts
    Jul 2, 2009
  4. A
    Replies:
    7
    Views:
    626
  5. , India

    pointer to an array vs pointer to pointer

    , India, Sep 20, 2011, in forum: C Programming
    Replies:
    5
    Views:
    442
    James Kuyper
    Sep 23, 2011
Loading...

Share This Page