Thread: How to return a character array from a function?

  1. #1
    Registered User
    Join Date
    Nov 2007
    Posts
    23

    How to return a character array from a function?

    what is the correct way of declaring a function that return an array of characters?

    Also how do return array of characters from within a local function?
    I tried use a pointer to the variable that was declared in the location function, sometimes, it gave incorrect result. maybe because of the lifetime of the local variable.

    Code:
    char *f ( char somearray[])
    {
    }

  2. #2
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    You can return an array with a pointer as long as it's not a local variable. If it is, you can make it static and it will be ok because the lifetime is like a global. You can also dynamically allocate an array and pass it back with a pointer, but then you'll have to free it later.

  3. #3
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    You don't.
    Pass the char* buffer & size of the buffer to the function and write to those parameters.
    Code:
    char* func( char* buf, int size )
    {
        char str[] = "Hello World";
    
        if ( size > strlen( str ) )
        {
            return strncpy( buf, str, (size - 1) );
        }
    
        return NULL; /* Error!  buf isn't big enough. */
    }
    Local arrays you create in a function disappear when the function returns. You'd have to allocate it with malloc() if you want a local variable to survive a function return, but then someone else has to delete it with free(). The method I showed above is the standard safer way to do it.
    You can return a char* pointer like above, or better might be to return an int (0 for success, otherwise the buffer size required)...

  4. #4
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by robwhit View Post
    You can return an array with a pointer as long as it's not a local variable. If it is, you can make it static and it will be ok because the lifetime is like a global. You can also dynamically allocate an array and pass it back with a pointer, but then you'll have to free it later.
    Oops, forgot about the static option. But then of course your code wouldn't be multithread safe...

  5. #5
    Registered User
    Join Date
    Nov 2007
    Posts
    23
    [QUOTE=cpjust;695015]You don't.
    Pass the char* buffer & size of the buffer to the function and write to those parameters.
    Code:
    char* func( char* buf, int size )
    {
        char str[] = "Hello World";
    
        if ( size > strlen( str ) )
        {
            return strncpy( buf, str, (size - 1) );
        }
    
        return NULL; /* Error!  buf isn't big enough. */
    }
    it is okay to do like this, but just what if we don want make changes to pointer which is passed as the function argument (buf).

    I think using malloc() and add one more arqument to the function prototype.
    so later on I can free the space claimed in the function.
    what do you think? is it good? m not so sure at all.

  6. #6
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Quote Originally Posted by whichet View Post
    what if we don want make changes to pointer which is passed as the function argument (buf).
    then make a copy of it.
    Quote Originally Posted by whichet View Post
    I think using malloc() and add one more arqument to the function prototype.
    so later on I can free the space claimed in the function.
    what do you think? is it good? m not so sure at all.
    yeah, like that.

  7. #7
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by whichet View Post
    I think using malloc() and add one more arqument to the function prototype.
    so later on I can free the space claimed in the function.
    what do you think? is it good? m not so sure at all.
    That's like using a public toilet without flushing. You're forcing other people to clean up your mess.

    If the person calling the function already has an array that they can use for the buffer, they can pass that to the function and then there's no call to malloc() and no need to call free() since the array is on the stack.
    Or if they need the buffer to live longer, they can do the malloc() themselves and obviously they'd need to free it somewhere down the road too; but at least they have the option of using malloc() or using an array.

  8. #8
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by cpjust View Post
    That's like using a public toilet without flushing. You're forcing other people to clean up your mess.

    If the person calling the function already has an array that they can use for the buffer, they can pass that to the function and then there's no call to malloc() and no need to call free() since the array is on the stack.
    Or if they need the buffer to live longer, they can do the malloc() themselves and obviously they'd need to free it somewhere down the road too; but at least they have the option of using malloc() or using an array.
    Which of course makes a big problem for the calling function if it does not know beforehead the target size of the buffer... So it should guess the size to be allocated - try to pass the allocated array to the child function, and when it fails due to unsuffitient buffer size - to reallocate the buffer with bigger size... Too much overhead.
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    In that case, you can do what some Win32 API does. Pass a NULL buffer and 0 size and the function should return the required size.
    Or you can make the function smart by taking a char** and if that char** is NULL and size == 0, then allocate memory in the char** argument.
    Or you can just take a char*, but the callee casts a char** to char* and passes it (the buffer being NULL) and size == 0 and the function will re-cast the char* to char** and allocate a buffer. Seems a bit more complex, but it hides the extra char** argument with a simple char*, as if the callee must pass a buffer.
    Or you can combine the first and second.
    Last edited by Elysia; 12-05-2007 at 01:30 PM.
    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.

  10. #10
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    In that case, you can do what some Win32 API does. Pass a NULL buffer and 0 size and the function should return the required size.
    Not just the Win32 API. Some POSIX and GNU functions do this as well. I can't think of any at the moment except for tmpnam(), which sort of does.

    Your second option sounds pretty convoluted . . . .
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  11. #11
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by dwks View Post
    Your second option sounds pretty convoluted . . . .
    Sounds a bit similar to the strtol() type of functions.

  12. #12
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    No, strtol() is like the first option:
    Or you can make the function smart by taking a char** and if that char** is NULL and size == 0, then allocate memory in the char** argument.
    No casting involved . . . .
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Kinda up to the programmer to use whatever you deem best. If the function takes char**, then you need to do an extra & when passing the argument, so you won't pass char**. But if you take char*, then you won't need it, but eh... whatever syntax you feel is better.
    But the first and maybe second are the best I think.
    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
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by dwks View Post
    No, strtol() is like the first option:

    No casting involved . . . .
    I took that as the second option. The first one was using the Win32 approach with passing the buffer and size.

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. New string functions
    By Elysia in forum C Programming
    Replies: 11
    Last Post: 03-28-2009, 05:03 AM
  3. Replies: 8
    Last Post: 03-10-2008, 11:57 AM
  4. Another weird error
    By rwmarsh in forum Game Programming
    Replies: 4
    Last Post: 09-24-2006, 10:00 PM
  5. mygets
    By Dave_Sinkula in forum C Programming
    Replies: 6
    Last Post: 03-23-2003, 07:23 PM