Thread: return pointer address from a function

  1. #1
    Registered User
    Join Date
    Apr 2015
    Location
    Philippines
    Posts
    9

    return pointer address from a function

    Sorry for the wrong title, what I meant to say was "return the array address from a function"

    I have a function that should return the address of a pointer to a string of characters but needs fixing.
    The code:
    Code:
    char * int_to_str(int an_int)
    {
        char str[100];
        /* some long process */
    
        return str;
    }
    Is the solution to add static to the statement: "char str[100];"?
    If the variable is local-static does it mean that it will never be removed from memory and will be sort of treated like a global variable but visible only to the function?
    Thank you
    Last edited by chris_oliver; 04-17-2015 at 07:37 AM. Reason: wrong title

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Is the solution to add static to the statement: "char str[100];"?
    That's one solution, yes. But it introduces other problems, re-entrancy being a huge one. A better approach in general would be to let the caller manage the buffer and pass it in to your function along with the maximum size:
    Code:
    char *int_to_str(int an_int, char *buf, size_t size);
    will be sort of treated like a global variable but visible only to the function?
    Yes.

    [edit]
    On a side note, I'm very interested in the /* some long process */ part. Number to string conversions are quite a bit trickier than they seem, and I enjoy seeing different approaches.
    [/edit]
    My best code is written with the delete key.

  3. #3
    Registered User
    Join Date
    Apr 2015
    Location
    Philippines
    Posts
    9
    Quote Originally Posted by Prelude View Post
    That's one solution, yes. But it introduces other problems, re-entrancy being a huge one. A better approach in general would be to let the caller manage the buffer and pass it in to your function along with the maximum size:
    Code:
    char *int_to_str(int an_int, char *buf, size_t size);
    Thanks for the reply. I actually thought of the same solution though I'm curious about the argument "size_t size". Is size_t a datatype of some sort?
    I'm interested to know more about the problem with re-entry, could you please elaborate on the possible problem?
    Thank you
    And I'll send the code for my approach, sorry I'm typing with mobile

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by chris_oliver
    Is size_t a datatype of some sort?
    Yes, it is an unsigned integer type that is the type of the result of the sizeof operator. It is available via <stddef.h> and some other standard headers.

    Quote Originally Posted by chris_oliver
    I'm interested to know more about the problem with re-entry, could you please elaborate on the possible problem?
    Consider that there's really only one array storing the string, yet the function could be called multiple times. If the function is called a second time before the caller copies the result string, the result for the second call would then be incorrectly treated as the result for the first call.

    As an example from the standard library, you might have encountered something similiar when using strtok.
    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

  5. #5
    Registered User
    Join Date
    Apr 2015
    Location
    Philippines
    Posts
    9
    Quote Originally Posted by laserlight View Post
    Consider that there's really only one array storing the string, yet the function could be called multiple times. If the function is called a second time before the caller copies the result string, the result for the second call would then be incorrectly treated as the result for the first call.

    As an example from the standard library, you might have encountered something similiar when using strtok.
    Sorry, I do not use too much other libraries except stdio. I would like to better understand what you've said about the second call so please bear with me. Correct me if I'm wrong but do you mean before the string is copied/used/printed?
    Code:
     
    str_ptr = int_to_str(int an_int);
    printf("%s\n",  str_ptr); // Used once
    The printf prints the string once and the function can be used again to convert another into string. If I have a charcter pointer called cptr and cptr2.
    So if I have this:
    #1 function call and convert then store to cptr1
    #2 print cptr1
    #3 function call and store to cptr2
    #4 print cptr2
    #5 print cptr1 again

    Correct me if I'm wrong. So it would mean that #5 would produce undesirable results because both cptr1 and cptr2 share the same address?

  6. #6
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Sorry, I do not use too much other libraries except stdio.
    stdio is fun, but the others are interesting too. Oddly enough, a quite robust integer to string conversion function is available in stdlib.h by the name of strtol. There's also an atoi, but just pretend that one doesn't exist, because it's evil and stupid.

    Correct me if I'm wrong. So it would mean that #5 would produce undesirable results because both cptr1 and cptr2 share the same address?
    Nope, that's it exactly. Both pointers refer to the same string, so changes to cptr2 would also be reflected in cptr1.
    My best code is written with the delete key.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Prelude
    Oddly enough, a quite robust integer to string conversion function is available in stdlib.h by the name of strtol.
    strtol is for string to (long) integer conversion though. Perhaps you are thinking of sprintf and snprintf from <stdio.h>?
    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

  8. #8
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Yes, thank you.
    My best code is written with the delete key.

  9. #9
    Registered User
    Join Date
    Apr 2015
    Location
    Philippines
    Posts
    9
    Thank you guys for the awesome replies and additional knowlwdge. Assuming that only one pointer catches the returned address from the function.
    This is my approach for the process

    Code:
     
    char * int_to_string(int an_int) 
    {
        static char str[100];
        int digits = 0,  temp;
    
        if(an_int == 0){
            str[0] = '0';
            str[1] =' \0';
       }else{
            temp = an_int;
            if(temp < 0){
                str[0] = '-' ;
                digits++;
                temp *= -1;
            } 
            while(temp > 0){
                digits++;
                temp /= 10;
            }
            str[digits] = '\0';
            temp = (an_int < 0)? (an_int * (-1)) :(an_int) ;
            while(temp > 0){
                str[digits -  1] = (temp%10) + '0';
                digits--;
                temp /= 10;
            } 
        } 
        return str;
    }
    Sorry I did not compile this, sorry for some errors but I would like to get your feedback on this process. Thank you

  10. #10
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    I would like to get your feedback on this process.
    I like it. As laserlight kindly pointed out, my mention of trickiness was in reference to the reverse process of converting a string to an integer. I have no excuse other than I was working on my strtod implementation lately, and had a weird bout of conceptual dyslexia. Your approach isn't much different from what I use on the back end for sprintf:
    Code:
    /*
        @description:
            Converts a long long value into its string representation using the given attributes.
    
            Attributes:
                * radix         -- The base of the represented number.
                * show_sign     -- Always show a positive sign.
                * alt_case      -- Represent hexadecimal digits in upper case.
                * ignore_locale -- Ignore the current locale in all cases if true.
    */
    char *_lltoa(char s[], long long value, int radix, int show_sign, int alt_case, int ignore_locale)
    {
        size_t i = 0;
    
        if (value < 0 || show_sign)
        {
            s[i++] = (value < 0) ? '-' : '+';
        }
    
        _ulltoa(&s[i], llabs(value), radix, alt_case, ignore_locale);
    
        return s;
    }
    
    /*
        @description:
            Converts an unsigned long long value into its string representation using the given attributes.
    
            Attributes:
                * radix         -- The base of the represented number.
                * alt_case      -- Represent hexadecimal digits in upper case if true.
                * ignore_locale -- Ignore the current locale in all cases if true.
    */
    char *_ulltoa(char s[], unsigned long long value, int radix, int alt_case, int ignore_locale)
    {
        const char *digits = alt_case ? "0123456789ABCDEF" : "0123456789abcdef";
    
        // Locale-specific grouping and separation information
        char *grouping = localeconv()->grouping;
        int group_size = *grouping, group_len = 0;
        size_t i = 0;
    
        if (value == 0)
        {
            s[i++] = '0'; // Special case to simplify the deconstruction loop
        }
        else
        {
            // Desconstruction loop. Build the string in reverse because we don't know how many digits are present
            while (value)
            {
                if (!ignore_locale && group_size && group_len++ == group_size)
                {
                    s[i++] = *localeconv()->thousands_sep;
    
                    // Only move to the next group if it exists, otherwise use the last valid group size
                    if (*grouping && *++grouping)
                    {
                        group_size = *grouping;
                    }
    
                    // Reset the group (to 1, since we're still copying a digit)
                    group_len = 1;
                }
    
                s[i++] = digits[value % radix];
                value /= radix;
            }
        }
    
        s[i--] = '\0';
    
        _strrev(s); // Fix the result ordering
    
        return s;
    }
    The size of the buffer isn't checked since I have unilateral control over it. Pretty much the only real differences are support for locale-based thousands separators and bases up to hexadecimal.

    Now if you want to talk about tricky, try writing a floating-point to string conversion.
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why return values from a function by ref, address
    By jim_0 in forum C++ Programming
    Replies: 1
    Last Post: 02-05-2014, 06:16 AM
  2. I need to see a function return address.
    By esbo in forum C Programming
    Replies: 55
    Last Post: 01-17-2013, 03:59 PM
  3. function calls and return address
    By acpower in forum C Programming
    Replies: 2
    Last Post: 06-05-2012, 05:58 AM
  4. how to return address of a pointer?
    By spotty in forum C Programming
    Replies: 1
    Last Post: 02-11-2010, 08:11 PM
  5. modifying a return address of a function
    By jay1313 in forum C Programming
    Replies: 3
    Last Post: 09-18-2008, 09:09 AM