pointer usage in c

Discussion in 'C Programming' started by rskeples@gmail.com, May 11, 2005.

  1. Guest

    I write a small program.

    char *foo(void);
    char *a = "I like C";

    int main(void) {
    if((strcmp(a,foo())) {
    printf("\n i like c");
    }
    }

    char *foo(void)
    {
    char b[100] = "I like C";
    return b;
    }

    My teacher tells me that this program not work since the return value
    from function foo() is not guaranteed to be preserved. I think this is
    correct usage of pointers.

    I dont think so. I think my teacher wrong.

    Please explain.
    thanks you
    Rick
     
    , May 11, 2005
    #1
    1. Advertising

  2. Richard Bos Guest

    wrote:

    > char *foo(void);
    > char *a = "I like C";
    >
    > int main(void) {
    > if((strcmp(a,foo())) {
    > printf("\n i like c");
    > }
    > }
    >
    > char *foo(void)
    > {
    > char b[100] = "I like C";
    > return b;
    > }
    >
    > My teacher tells me that this program not work since the return value
    > from function foo() is not guaranteed to be preserved. I think this is
    > correct usage of pointers.
    >
    > I dont think so. I think my teacher wrong.


    Your teacher is(!) right. You're returning the address of an auto
    ("local") array from foo(). This array, like all auto objects, has
    automatic duration, which means that once you return from foo(), it goes
    out of existence, and any attempt to use it invokes undefined behaviour,
    which means it may do anything from appearing to work correctly to crash
    hard. Sure, it may _look_ like it still exists after the return, in this
    simple test program. However, you cannot rely on this at all. In any
    more realistic program you're likely to read garbage.

    Richard
     
    Richard Bos, May 11, 2005
    #2
    1. Advertising

  3. T.M. Sommers Guest

    wrote:
    > I write a small program.


    #include <string.h>

    > char *foo(void);
    > char *a = "I like C";
    >
    > int main(void) {
    > if((strcmp(a,foo())) {
    > printf("\n i like c");


    You should in general terminate an output line with a newline in
    order to guarantee that it appears.

    > }
    > }
    >
    > char *foo(void)
    > {
    > char b[100] = "I like C";
    > return b;
    > }
    >
    > My teacher tells me that this program not work since the return value
    > from function foo() is not guaranteed to be preserved. I think this is
    > correct usage of pointers.
    >
    > I dont think so. I think my teacher wrong.


    Your teacher is correct. The array b is not guaranteed to
    continue to exist after foo() returns. It might, for instance,
    be in a location that is not accessible after the function
    returns, or it might get overwritten. Make it static and it will
    work.

    --
    Thomas M. Sommers -- -- AB2SB
     
    T.M. Sommers, May 11, 2005
    #3
  4. writes:
    > I write a small program.
    >
    > char *foo(void);
    > char *a = "I like C";
    >
    > int main(void) {
    > if((strcmp(a,foo())) {
    > printf("\n i like c");
    > }
    > }
    >
    > char *foo(void)
    > {
    > char b[100] = "I like C";
    > return b;
    > }
    >
    > My teacher tells me that this program not work since the return value
    > from function foo() is not guaranteed to be preserved. I think this is
    > correct usage of pointers.
    >
    > I dont think so. I think my teacher wrong.


    As others have pointed out, your teacher is right.

    Your array b is local to the function foo. As soon as foo returns,
    the array ceases to exist, and any attempt to refer to it will invoke
    undefined behavior.

    You've probably been misled by the fact that the program *appears* to
    work properly. That's the worst thing about undefined behavior; it's
    not guaranteed to blow up. What probably happens in your program (for
    a typical C implementation) is that the memory that the array occupied
    is still there; it's just beyond the top of the stack. It *could* be
    re-used for some other purpose. For example, an interrupt could be
    triggered after foo() returns and before you use the value, clobbering
    it. Or the system could mark the memory space as unavailable, causing
    a trap when you try to access it. But the most likely thing is that
    it's still right where you left it. Accessing it is still an error,
    but the implementation isn't required to detect the error.

    By returning from foo() you've told the system that you're finished
    with the array. By attempting to use the array afterwards, you're
    lying to the system. It's not obligated to show you any kind of
    mercy. So don't do 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, May 11, 2005
    #4
  5. On Wed, 11 May 2005 00:01:06 -0700, rskeples wrote:

    > I write a small program.
    >
    > char *foo(void);
    > char *a = "I like C";
    >
    > int main(void) {
    > if((strcmp(a,foo())) {
    > printf("\n i like c");
    > }
    > }
    >
    > char *foo(void)
    > {
    > char b[100] = "I like C";
    > return b;
    > }
    >
    > My teacher tells me that this program not work since the return value
    > from function foo() is not guaranteed to be preserved. I think this is
    > correct usage of pointers.


    The problem is not with the return value directly, it is with what the
    return value is pointing at. A pointer value is only valid as long as the
    thing it points at still exists. The return value of foo() isn't b itself
    or a copy of b, it is a pointer to (the first element of) b. When foo()
    returns all of its automatic variables cease to exist and that includes b,
    and so any pointer to b becomes invalid. In main() you are trying to use
    the value of an invalid pointer which gives undefined behaviour.

    > I dont think so. I think my teacher wrong.


    Remember that a pointer and what it points at are separate things and you
    have to consider both.

    Lawrence
     
    Lawrence Kirby, May 11, 2005
    #5
  6. > My teacher tells me that this program not work since the return value
    > from function foo() is not guaranteed to be preserved. I think this is
    > correct usage of pointers.


    Your teacher is correct. The memory for "b" is garbage once the
    function returns. In order to make it right, you need to allocate
    memory from the heap, and copy the string into the heap.

    Here is an untested function, but which should do you right:

    char *foo(void)
    {
    char b[100] = "I like C"; /* this will go away when the function returns */
    char *c = malloc((strlen(b) + 1) * sizeof(char)); /* malloc enough
    memory to hold "I like C" -- this will NOT go away when the function
    returns */
    strcpy(c, b); /* copy the contents of b to c */

    return c; /* return c */
    }

    Note that since you allocated the memory with malloc, when you are
    finished with it you MUST deallocate it with free().

    Jon
    ----
    Learn to program using Linux assembly language
    http://www.cafeshops.com/bartlettpublish.8640017
     
    Jonathan Bartlett, May 11, 2005
    #6
  7. Jirka Klaue Guest

    Jonathan Bartlett:
    ....
    > return c; /* return c */


    Very enlightening comment. :)

    Jirka
     
    Jirka Klaue, May 11, 2005
    #7
  8. wrote on 11/05/05 :
    > char *foo(void);
    > char *a = "I like C";
    >
    > int main(void) {
    > if((strcmp(a,foo())) {
    > printf("\n i like c");
    > }
    > }
    >
    > char *foo(void)
    > {
    > char b[100] = "I like C";
    > return b;
    > }
    >
    > My teacher tells me that this program not work since the return value
    > from function foo() is not guaranteed to be preserved. I think this is
    > correct usage of pointers.
    >
    > I dont think so. I think my teacher wrong.


    Yes, so is my compiler...

    main.c:13: warning: initialization discards qualifiers from pointer
    target type main.c: In function `main_':
    main.c:16: warning: implicit declaration of function `strcmp'
    main.c:16: parse error before '{' token
    main.c: In function `foo':
    main.c:24: warning: function returns address of local variable

    "Please engage your brain..." (c) Dan Pop...

    --
    Emmanuel
    The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
    The C-library: http://www.dinkumware.com/refxc.html

    ..sig under repair
     
    Emmanuel Delahaye, May 11, 2005
    #8
  9. (supersedes <>)

    wrote on 11/05/05 :
    > char *foo(void);
    > char *a = "I like C";
    >
    > int main(void) {
    > if((strcmp(a,foo())) {
    > printf("\n i like c");
    > }
    > }
    >
    > char *foo(void)
    > {
    > char b[100] = "I like C";
    > return b;
    > }
    >
    > My teacher tells me that this program not work since the return value
    > from function foo() is not guaranteed to be preserved. I think this is
    > correct usage of pointers.
    >
    > I dont think so. I think my teacher wrong.


    Yes, so is my compiler...

    main.c:13: warning: initialization discards qualifiers from pointer
    target type main.c: In function `main_':
    main.c:16: warning: implicit declaration of function `strcmp'
    main.c:16: parse error before '{' token
    main.c: In function `foo':
    main.c:24: warning: function returns address of local variable

    "Please engage your brain..." (c) Dan Pop...

    #include <string.h>
    #include <stdio.h>

    char const *foo (void)
    {
    char const *b = "I like C";
    return b;
    }

    int main (void)
    {
    char const *a = "I like C";

    if (strcmp (a, foo ()) == 0)
    {
    printf ("I like c\n");
    }
    return 0;
    }

    --
    Emmanuel
    The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
    The C-library: http://www.dinkumware.com/refxc.html

    ..sig under repair
     
    Emmanuel Delahaye, May 11, 2005
    #9
  10. Hi All,

    I think the following code will also work:

    char *foo( )
    {
    return "I like C";
    }

    since string-literals have static life-time ( regardless of scope) !.

    Nitin
     
    Nitin Bhardwaj, May 12, 2005
    #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. Replies:
    10
    Views:
    731
    Chris Torek
    Feb 4, 2005
  2. jimjim
    Replies:
    16
    Views:
    861
    Jordan Abel
    Mar 28, 2006
  3. Replies:
    4
    Views:
    1,309
    Fred Zwarts
    Jul 2, 2009
  4. A
    Replies:
    7
    Views:
    649
  5. , India

    pointer to an array vs pointer to pointer

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

Share This Page