Thread: return value from function (out of scope)

  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    72

    return value from function (out of scope)

    Hi All

    Consider the following function
    Code:
    char* getSomething() {
       char* str = "hello" ;
       return str ;
    }
    which I can use as follows
    Code:
       char* output = malloc( 6 * sizeof(*output) ) ;
       output = getSomething() ;
    or
    Code:
       char *output = getSomething() ;
    I would say that the last usage should be avoided, right?

    But an other problem might be char* str, because it goes out of scope when the function finishes, meaning the memory will be available again. Is this statement right ?

    If so, it could then give problems when using 'output'. And in which situation can you return a pointer ?

    Any comments on the above, because I have the feeling I don't really understand this stuff!

    thnx a lot
    LuCa

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by jeanluca View Post
    Hi All

    Consider the following function
    Code:
    char* getSomething() {
       char* str = "hello" ;
       return str ;
    }
    which I can use as follows
    Code:
       char* output = malloc( 6 * sizeof(*output) ) ;
       output = getSomething() ;
    or
    Code:
       char *output = getSomething() ;
    I would say that the last usage should be avoided, right?
    The first one is to be avoided at all costs as str disappears the instant the function that contains it returns unless str is on the heap instead of on the stack.
    Quote Originally Posted by jeanluca View Post
    But an other problem might be char* str, because it goes out of scope when the function finishes, meaning the memory will be available again. Is this statement right ?
    Yes, when the stack is popped str is not visible anymore leaving you with a dangling pointer in the caller ie output now points to a non-existent location.
    Quote Originally Posted by jeanluca View Post
    If so, it could then give problems when using 'output'. And in which situation can you return a pointer ?
    As long as str isn't on the stack ie a local variable.

  3. #3
    Registered User
    Join Date
    May 2009
    Posts
    72
    thnx for your quick response!

    Its all clear except the fact that, suppose, the returned value is on the heap, why the first usage is wrong!

  4. #4
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by jeanluca View Post
    thnx for your quick response!

    Its all clear except the fact that, suppose, the returned value is on the heap, why the first usage is wrong!
    If the first value is on the heap ie malloc()'d then it's correct, but if it's on the stack then it's wrong.
    Check out this link, as IMO it tackles the notion of the dangling pointer very well.

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Code:
    char* getSomething() {
       char* str = "hello" ;
       return str ;
    }
    This is actually safe because the text is stored in memory for the duration of the program. Had you done this, though, that would not be the case:

    Code:
    char* getSomething() {
       char str[] = "hello" ;
       return str ;
    }
    In that case, it would be a local variable and could not be returned from the function.

    At any rate, I would avoid returning malloc'ed memory as well, as this is a very common source of memory leaks. The best way, generally, is to have to user pass a buffer and buffer length to the function, ie:

    Code:
    char* foo(char* buffer, size_t max_length)
    {
    	char text[] = "baz";
    	size_t length = strlen(text);
    	if(length >= max_length)
    		return NULL;
    	strncpy(buffer, text, length);
    	return buffer;
    }
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  6. #6
    Registered User
    Join Date
    May 2009
    Posts
    72
    Code:
    char* getSomething() {
       char* str = "hello" ;
       return str ;
    }
    is str stored on the heap ? I would say it local -> stack!

    itCbitC thnx for the tutorial!

  7. #7
    DESTINY BEN10's Avatar
    Join Date
    Jul 2008
    Location
    in front of my computer
    Posts
    804
    Quote Originally Posted by itCbitC View Post
    The first one is to be avoided at all costs as str disappears the instant the function that contains it returns unless str is on the heap instead of on the stack.

    Yes, when the stack is popped str is not visible anymore leaving you with a dangling pointer in the caller ie output now points to a non-existent location.

    As long as str isn't on the stack ie a local variable.
    Isn't this true with an ordinary variable. For eg.
    Code:
    int func(void)
    {
    int sum;
    sum=32;
    return sum;
    }
    Whenever the function is returned sum gets destroyed. So why is this only considered with pointers?
    HOPE YOU UNDERSTAND.......

    By associating with wise people you will become wise yourself
    It's fine to celebrate success but it is more important to heed the lessons of failure
    We've got to put a lot of money into changing behavior


    PC specifications- 512MB RAM, Windows XP sp3, 2.79 GHz pentium D.
    IDE- Microsoft Visual Studio 2008 Express Edition

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by BEN10
    Whenever the function is returned sum gets destroyed. So why is this only considered with pointers?
    Right. So the local variable is destroyed when the function goes out of scope. If you return a pointer to the local variable, one can then reason that the caller would get a copy of a pointer to a variable that no longer exists. In the case of buffer, the caller would get a pointer to the first element of an array that no longer exists.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    DESTINY BEN10's Avatar
    Join Date
    Jul 2008
    Location
    in front of my computer
    Posts
    804
    Still I'm very much confused. I dont understand how does all this returning procedure works fine if the variable gets destroyed(even in simpler cases where no pointer is involved).
    HOPE YOU UNDERSTAND.......

    By associating with wise people you will become wise yourself
    It's fine to celebrate success but it is more important to heed the lessons of failure
    We've got to put a lot of money into changing behavior


    PC specifications- 512MB RAM, Windows XP sp3, 2.79 GHz pentium D.
    IDE- Microsoft Visual Studio 2008 Express Edition

  10. #10
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by jeanluca View Post
    Code:
    char* getSomething() {
       char* str = "hello" ;
       return str ;
    }
    is str stored on the heap ? I would say it local -> stack!

    itCbitC thnx for the tutorial!
    The variable str itself is local and therefore stored on the stack. It disappears (is popped off the stack) at the end of the function. However, the value it stores and is returning to the caller is the address of the string literal "hello" which exists in the program's read-only data segment. This address will exist throughout the program's existence and is therefore safe to return using this function.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  11. #11
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059

    Talking

    Quote Originally Posted by jeanluca View Post
    Code:
    char* getSomething() {
       char* str = "hello" ;
       return str ;
    }
    is str stored on the heap ? I would say it local -> stack!
    Yes str is stored on the stack as it is local to getSomething() and disappears when it returns.
    OTOH string "hello" remains in existence for the duration of the program as it's stored in the data (not the stack) segment.
    When getSomething() returns, the calling function simply receives the location of the string literal "hello".

  12. #12
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by BEN10 View Post
    Still I'm very much confused. I dont understand how does all this returning procedure works fine if the variable gets destroyed(even in simpler cases where no pointer is involved).
    Where pointers are not involved, the value/literal to be returned is copied from the stack frame of the callee into the stack frame of the caller. Storage is already allocated in the stack frame of the callee for the value being returned. Did you try to Google it?

    [edit] Here's a link on stack howto [/edit]
    Last edited by itCbitC; 06-23-2009 at 09:34 AM.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by jeanluca View Post
    Hi All

    Consider the following function
    Code:
    char* getSomething() {
       char* str = "hello" ;
       return str ;
    }
    which I can use as follows
    Code:
       char* output = malloc( 6 * sizeof(*output) ) ;
       output = getSomething() ;
    or
    Code:
       char *output = getSomething() ;
    I would say that the last usage should be avoided, right?

    But an other problem might be char* str, because it goes out of scope when the function finishes, meaning the memory will be available again. Is this statement right ?

    If so, it could then give problems when using 'output'. And in which situation can you return a pointer ?

    Any comments on the above, because I have the feeling I don't really understand this stuff!

    thnx a lot
    LuCa
    Note that the first use is bad, since you are only assigning a new value to the pointer, and not to the allocated memory.
    The allocated memory's address is stored in the pointer and is lost once you assign another value to the pointer from the returned function, thus creating a memory leak.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by Elysia View Post
    Note that the first use is bad, since you are only assigning a new value to the pointer, and not to the allocated memory.
    The allocated memory's address is stored in the pointer and is lost once you assign another value to the pointer from the returned function, thus creating a memory leak.
    IMHO that's not what's happening here as the handle to the string "hello" is being returned to the caller instead of being discarded (creating a memory leak).

  15. #15
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I think Elysia was referring to this (the first usage of the function):
    Code:
       char* output = malloc( 6 * sizeof(*output) ) ;
       output = getSomething() ;
    where the original six characters of output do indeed leak away.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How can I make this code more elegant?
    By ejohns85 in forum C++ Programming
    Replies: 3
    Last Post: 04-02-2009, 08:55 AM
  2. Function return value conflict
    By cashmerelc in forum C Programming
    Replies: 6
    Last Post: 11-12-2007, 02:05 PM
  3. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM
  4. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM
  5. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM