Avoid using malloc?

Discussion in 'C Programming' started by Johs32, Mar 2, 2006.

  1. Johs32

    Johs32 Guest

    When I make a pointer I have read that if I would like to use it in another
    function, I need to malloc it first else it will disapear after the
    function returns. In this code I do not use malloc, but it still works and
    the function print_me() prints the correct text.

    Why does it work eventhough I do not use malloc?

    johs
     
    Johs32, Mar 2, 2006
    #1
    1. Advertising

  2. Johs32 said:

    > When I make a pointer I have read that if I would like to use it in
    > another function, I need to malloc it first else it will disapear after
    > the function returns. In this code


    In which code?

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Mar 2, 2006
    #2
    1. Advertising

  3. Johs32

    Michael Mair Guest

    Johs32 schrieb:
    > When I make a pointer I have read that if I would like to use it in another
    > function, I need to malloc it first else it will disapear after the
    > function returns. In this code I do not use malloc, but it still works and
    > the function print_me() prints the correct text.
    >
    > Why does it work eventhough I do not use malloc?


    Please provide compiling code, ideally stripped down to the
    situation you are referring to -- otherwise there is always
    the danger of misunderstandings.

    Example 1: The following is legal:

    void foo (long *bar);
    void baz (void);

    int main (void)
    {
    baz();
    return 0;
    }

    void baz (void)
    {
    long qux = 17;
    long *quux = &qux;
    foo(quux);
    }

    void foo (long *bar)
    {
    *bar /= 2;
    }

    Example 2: The following is not legal:

    long *foo (void);
    void baz (void);

    int main (void)
    {
    baz();
    return 0;
    }

    void baz (void)
    {
    long *quux = foo();
    *quux -= 2;
    }

    void foo (long *bar)
    {
    long bar = 42;
    long *qux = &bar;
    return qux;
    }

    I did not test either example.
    Even if you are in the situation of example 2, it is
    perfectly possible that it works -- now. This can
    change when compiling it on another operating system,
    platform or with another compiler or even when just
    adding another function to your code.

    Example 3: malloc()-Version of Example 2; legal

    #include <stdlib.h>

    long *foo (void);
    void baz (void);

    int main (void)
    {
    baz();
    return 0;
    }

    void baz (void)
    {
    long *quux = foo();
    if (quux != NULL) {
    *quux -= 2;
    }
    free(quux);
    }

    void foo (long *bar)
    {
    long *qux = malloc(sizeof *qux);
    if (qux != NULL) {
    *qux = 42;
    }
    return qux;
    }


    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, Mar 2, 2006
    #3
  4. Johs32

    Kevin Handy Guest

    Johs32 wrote:
    > When I make a pointer I have read that if I would like to use it in another
    > function, I need to malloc it first else it will disapear after the
    > function returns. In this code I do not use malloc, but it still works and
    > the function print_me() prints the correct text.
    >
    > Why does it work eventhough I do not use malloc?


    Blind stupid luck is the most likely answer.

    If that is the level of reliability you are looking
    for in your programs, then go ahead and use it.

    btw: What code?

    ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
     
    Kevin Handy, Mar 2, 2006
    #4
  5. Johs32 <> writes:
    > When I make a pointer I have read that if I would like to use it in another
    > function, I need to malloc it first else it will disapear after the
    > function returns. In this code I do not use malloc, but it still works and
    > the function print_me() prints the correct text.
    >
    > Why does it work eventhough I do not use malloc?


    Why does *what* work? How do you "make" the pointer?

    Show us some code, preferably a complete program.

    But first, take a look at questions 7.5a and 7.5b in the comp.lang.c
    FAQ, <http://www.c-faq.com/>.

    --
    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, Mar 2, 2006
    #5
  6. Johs32

    Johs32 Guest

    ups forgot the code:


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

    void print_me(char * string)
    {


    printf("%s\n",string);
    }


    int main()
    {
    char *string = "bopla";
    print_me(string);
    return 0;
    }
     
    Johs32, Mar 2, 2006
    #6
  7. Johs32

    Pedro Graca Guest

    Johs32 wrote:
    > Why does it work eventhough I do not use malloc?


    Undefined behaviour includes doing what the programmer expects.

    --
    If you're posting through Google read <http://cfaj.freeshell.org/google>
     
    Pedro Graca, Mar 2, 2006
    #7
  8. Johs32 said:

    > #include<stdio.h>
    > #include<stdlib.h>
    >
    > void print_me(char * string)
    > {
    > printf("%s\n",string);
    > }
    >
    >
    > int main()
    > {
    > char *string = "bopla";


    This pointer points to a string literal, which has static storage duration
    and therefore exists for the duration of the program. Nothing wrong with
    this code (although I'd make it const char * if you're pointing at a string
    literal).

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Mar 2, 2006
    #8
  9. Johs32

    Johs32 Guest

    Richard Heathfield wrote:

    > Johs32 said:
    >
    >> #include<stdio.h>
    >> #include<stdlib.h>
    >>
    >> void print_me(char * string)
    >> {
    >> printf("%s\n",string);
    >> }
    >>
    >>
    >> int main()
    >> {
    >> char *string = "bopla";

    >
    > This pointer points to a string literal, which has static storage duration
    > and therefore exists for the duration of the program. Nothing wrong with
    > this code (although I'd make it const char * if you're pointing at a
    > string literal).
    >



    Ok but what is *string was a pointer to a struct or something that is not a
    "literal", can I still omit malloc?
     
    Johs32, Mar 2, 2006
    #9
  10. Johs32 said:

    > Ok but what is *string was a pointer to a struct or something that is not
    > a "literal", can I still omit malloc?


    If you need to store data, you need somewhere to store it.

    String literals are sorted out for you. If you wish to capture and store a
    string at runtime, you will need to allocate storage for it. The malloc
    function offers one way to do this.


    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Mar 2, 2006
    #10
  11. Johs32 <> writes:
    > Richard Heathfield wrote:
    >
    >> Johs32 said:
    >>
    >>> #include<stdio.h>
    >>> #include<stdlib.h>
    >>>
    >>> void print_me(char * string)
    >>> {
    >>> printf("%s\n",string);
    >>> }
    >>>
    >>>
    >>> int main()
    >>> {
    >>> char *string = "bopla";

    >>
    >> This pointer points to a string literal, which has static storage duration
    >> and therefore exists for the duration of the program. Nothing wrong with
    >> this code (although I'd make it const char * if you're pointing at a
    >> string literal).

    >
    > Ok but what is *string was a pointer to a struct or something that is not a
    > "literal", can I still omit malloc?


    It depends on how you allocate it and what you do with it. We
    couldn't answer your original question without seeing code; we can't
    answer this one without seeing code either.

    If you declare a local variable (i.e., declare it inside a function
    without using the "static" keyword), that variable ceases to exist
    when you leave the function. If you create a pointer to a local
    variable, returning that pointer to a caller invokes undefined
    behavior -- but you can safely pass the pointer to another function,
    since the variable continues to exist until the outer function
    terminates.

    Returning the *value* of a local variable is ok.

    --
    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, Mar 2, 2006
    #11
  12. Johs32

    Pedro Graca Guest

    Johs32 wrote:
    > ups forgot the code:
    >
    >
    > #include<stdio.h>
    > #include<stdlib.h>
    >
    > void print_me(char * string)
    > {
    >
    >
    > printf("%s\n",string);
    > }
    >
    >
    > int main()
    > {
    > char *string = "bopla";
    > print_me(string);
    > return 0;
    > }


    And now you forgot the question.

    Please provide context, even when following-up to your own posts.
    Also read the link in my signature.

    --
    If you're posting through Google read <http://cfaj.freeshell.org/google>
     
    Pedro Graca, Mar 2, 2006
    #12
  13. Johs32

    Micah Cowan Guest

    Johs32 <> writes:

    > Richard Heathfield wrote:
    >
    > > Johs32 said:
    > >
    > >> #include<stdio.h>
    > >> #include<stdlib.h>
    > >>
    > >> void print_me(char * string)
    > >> {
    > >> printf("%s\n",string);
    > >> }
    > >>
    > >>
    > >> int main()
    > >> {
    > >> char *string = "bopla";

    > >
    > > This pointer points to a string literal, which has static storage duration
    > > and therefore exists for the duration of the program. Nothing wrong with
    > > this code (although I'd make it const char * if you're pointing at a
    > > string literal).
    > >

    >
    > Ok but what is *string was a pointer to a struct or something that is not a
    > "literal", can I still omit malloc?


    Well, given the order of calling that you had, it still would've been
    fine, even if it had been an object of automatic storage duration:

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

    void print_me(const char *string)
    /* ^^^^^ I consider this a bit better. */
    {
    printf("%s\n", string);
    /* The above could more easily be: puts(string); */
    }

    int main(void)
    /* ^^^^ this is very much worth spelling out: not the same as (). */

    char string[] = "bopla";
    print_me(string);
    return EXIT_SUCCESS;
    }
    --------------------------------------------------

    This works, because the automatically-allocated object exist until
    main() exits.

    However, if you had reversed the calling:

    ----------------- BAD CODE !! --------------------
    #include <stdio.h>
    #include <stdlib.h>

    char *get_string(void)
    {
    char string[] = "message";
    return string; /* string[] disappears after this ! */
    }

    int main(void)
    {
    puts(get_string());
    return EXIT_SUCCESS;
    }
    ----------------- BAD CODE !! --------------------

    This causes problems, for the reason explained in the comment.
    You could fix it by declaring string[] as:

    static char string[] = "message";

    which would give it a static storage duration (same lifetime as a
    literal).

    Or--especially if you don't know how big it will need to be, or if
    you need a separate copy of the string for each caller (perhaps you
    intend for it to be modified)--you'll need to malloc() it. Always make
    sure you free() it again later, so the system can reclaim the lost
    memory.

    HTH,
    Micah
     
    Micah Cowan, Mar 2, 2006
    #13
  14. Johs32

    Jordan Abel Guest

    On 2006-03-02, Johs32 <> wrote:
    > Richard Heathfield wrote:
    >
    >> Johs32 said:
    >>
    >>> #include<stdio.h>
    >>> #include<stdlib.h>
    >>>
    >>> void print_me(char * string)
    >>> {
    >>> printf("%s\n",string);
    >>> }
    >>>
    >>>
    >>> int main()
    >>> {
    >>> char *string = "bopla";

    >>
    >> This pointer points to a string literal, which has static storage duration
    >> and therefore exists for the duration of the program. Nothing wrong with
    >> this code (although I'd make it const char * if you're pointing at a
    >> string literal).
    >>

    >
    >
    > Ok but what is *string was a pointer to a struct or something that is not a
    > "literal", can I still omit malloc?


    passing it down without using malloc is fine - the problem comes when
    you're _returning_ something.
     
    Jordan Abel, Mar 2, 2006
    #14
  15. Johs32

    gooch Guest

    Michael Mair wrote:
    > Johs32 schrieb:
    > Please provide compiling code, ideally stripped down to the
    > situation you are referring to -- otherwise there is always
    > the danger of misunderstandings.
    >
    > Example 1: The following is legal:
    >
    > void foo (long *bar);
    > void baz (void);
    >
    > int main (void)
    > {
    > baz();
    > return 0;
    > }
    >
    > void baz (void)
    > {
    > long qux = 17;
    > long *quux = &qux;
    > foo(quux);
    > }
    >
    > void foo (long *bar)
    > {
    > *bar /= 2;
    > }
    >


    This seems fine although useless

    > Example 2: The following is not legal:
    >
    > long *foo (void);
    > void baz (void);
    >
    > int main (void)
    > {
    > baz();
    > return 0;
    > }
    >
    > void baz (void)
    > {
    > long *quux = foo();


    doesn't foo have an argument?

    > *quux -= 2;
    > }
    >
    > void foo (long *bar)
    > {
    > long bar = 42;
    > long *qux = &bar;
    > return qux;


    This is a void function with a return value, why?
    > }
    >
    > I did not test either example.
    > Even if you are in the situation of example 2, it is
    > perfectly possible that it works


    I could be wrong but I don't think number 2 will even compile.

    > Example 3: malloc()-Version of Example 2; legal
    >
    > #include <stdlib.h>
    >
    > long *foo (void);
    > void baz (void);
    >
    > int main (void)
    > {
    > baz();
    > return 0;
    > }
    >
    > void baz (void)
    > {
    > long *quux = foo();


    again there is an argument to foo.

    > if (quux != NULL) {

    you will never get here.
    > *quux -= 2;
    > }

    what are you freeing here as you bnever allocated anything
    > free(quux);
    > }
    >
    > void foo (long *bar)
    > {
    > long *qux = malloc(sizeof *qux);
    > if (qux != NULL) {
    > *qux = 42;
    > }
    > return qux;


    You are agin returning a value from a void function
    > }


    Again I could be wrong but I don't think this will compile. Am I
    missing something here.
     
    gooch, Mar 3, 2006
    #15
  16. Johs32

    Michael Mair Guest

    gooch schrieb:
    > Michael Mair wrote:
    >
    >>Johs32 schrieb:
    >>Please provide compiling code, ideally stripped down to the
    >>situation you are referring to -- otherwise there is always
    >>the danger of misunderstandings.
    >>
    >>Example 1: The following is legal:
    >>
    >>void foo (long *bar);
    >>void baz (void);
    >>
    >>int main (void)
    >>{
    >> baz();
    >> return 0;
    >>}
    >>
    >>void baz (void)
    >>{
    >> long qux = 17;
    >> long *quux = &qux;
    >> foo(quux);
    >>}
    >>
    >>void foo (long *bar)
    >>{
    >> *bar /= 2;
    >>}

    >
    > This seems fine although useless


    Yes. All the examples are fine and useless. I wanted
    to describe the possible situations.

    >>Example 2: The following is not legal:
    >>
    >>long *foo (void);
    >>void baz (void);
    >>
    >>int main (void)
    >>{
    >> baz();
    >> return 0;
    >>}
    >>
    >>void baz (void)
    >>{
    >> long *quux = foo();

    >
    >
    > doesn't foo have an argument?


    According to the prototype, it does not.
    I just forgot to change the prototype for the function
    definition accordingly -- as I said, untested.
    >
    >
    >> *quux -= 2;
    >>}
    >>
    >>void foo (long *bar)

    long *foo (void)

    >>{
    >> long bar = 42;
    >> long *qux = &bar;
    >> return qux;

    >
    >
    > This is a void function with a return value, why?


    See above.
    >
    >>}
    >>
    >>I did not test either example.
    >>Even if you are in the situation of example 2, it is
    >>perfectly possible that it works

    >
    >
    > I could be wrong but I don't think number 2 will even compile.
    >
    >
    >>Example 3: malloc()-Version of Example 2; legal
    >>
    >>#include <stdlib.h>
    >>
    >>long *foo (void);
    >>void baz (void);
    >>
    >>int main (void)
    >>{
    >> baz();
    >> return 0;
    >>}
    >>
    >>void baz (void)
    >>{
    >> long *quux = foo();

    >
    >
    > again there is an argument to foo.
    >
    >
    >> if (quux != NULL) {

    >
    > you will never get here.
    >
    >> *quux -= 2;
    >> }

    >
    > what are you freeing here as you bnever allocated anything
    >
    >> free(quux);
    >>}
    >>
    >>void foo (long *bar)

    long *foo (void)
    >>{
    >> long *qux = malloc(sizeof *qux);
    >> if (qux != NULL) {
    >> *qux = 42;
    >> }
    >> return qux;

    >
    >
    > You are agin returning a value from a void function
    >
    >>}

    >
    > Again I could be wrong but I don't think this will compile. Am I
    > missing something here.


    Same applies here.
    Thanks for asking for a correction :)


    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, Mar 3, 2006
    #16
  17. Johs32

    Ron Lima Guest

    > Ok but what is *string was a pointer to a struct or something that is not a
    > "literal", can I still omit malloc?


    If you make it point to some place in memory, yes. For instance:

    #include <stdio.h>

    struct test {
    int a;
    char b[40];
    };
    int main (void) {
    struct test s = {10, "Hello there"};
    struct test *p = &s;

    printf ("%d %s\n", p->a, p->b);
    return 0;
    }

    In this case, p points to the storage provided by s. Usually you
    allocate memory when you don't know how much information you will have
    to deal in memory and this fact makes it impossible to pre-allocate
    storage for it. For instance, imagine that you need to read an entire
    file to memory in order to do some processing on it. Since the file can
    have an arbitrary lenght, you just can't pre-allocate memory and,
    therefore, you will need to allocate memory for your buffer before
    reading the entire file.
     
    Ron Lima, Mar 3, 2006
    #17
  18. On Thu, 02 Mar 2006 21:30:34 +0100, Johs32 <> wrote:

    >Richard Heathfield wrote:
    >
    >> Johs32 said:
    >>
    >>> #include<stdio.h>
    >>> #include<stdlib.h>
    >>>
    >>> void print_me(char * string)
    >>> {
    >>> printf("%s\n",string);
    >>> }
    >>>
    >>>
    >>> int main()
    >>> {
    >>> char *string = "bopla";

    >>
    >> This pointer points to a string literal, which has static storage duration
    >> and therefore exists for the duration of the program. Nothing wrong with
    >> this code (although I'd make it const char * if you're pointing at a
    >> string literal).
    >>

    >
    >
    >Ok but what is *string was a pointer to a struct or something that is not a
    >"literal", can I still omit malloc?


    When your function receives a pointer from a calling routine, you do
    not necessarily need to call malloc.

    If the calling routine tries to pass you an uninitialized
    pointer, that routine invokes undefined behavior and anything can
    happen before, during, or after your function executes.

    Now that you know the pointer has been initialized to some
    value, it may be appropriate to check if that value is NULL. You do
    this if your function would normally try to dereference the pointer
    since dereferencing a NULL pointer would invoke undefined behavior.

    If you want to change the value of the pointer (the address it points
    to), you could call malloc. You could also assign it the address of
    an object of the correct type that happens to be in scope to your
    function. Whether you do this or not depends on the nature of your
    function. Since C passes arguments to functions by value, any change
    you make to the pointer's value is local to your function unless you
    somehow "export" the new value to the calling routine, as with a
    return statement.

    In my experience, most functions that receive pointers as arguments do
    not call malloc but use the value of the pointer as passed by the
    calling routine. I think you should go back and reread the text that
    raised your initial question. All automatic variables local to your
    function, including parameters, disappear when your function returns.
    However, this has no affect on the variables in the calling routine
    that may have been used as arguments.


    Remove del for email
     
    Barry Schwarz, Mar 12, 2006
    #18
    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. Alexander Malkis
    Replies:
    8
    Views:
    551
    Alexander Malkis
    Apr 14, 2004
  2. Roger23
    Replies:
    2
    Views:
    1,039
    Roger23
    Oct 12, 2006
  3. John
    Replies:
    13
    Views:
    734
  4. ravi
    Replies:
    0
    Views:
    481
  5. Peter
    Replies:
    34
    Views:
    2,055
    Richard Tobin
    Oct 22, 2004
Loading...

Share This Page