returning a string array from function on stack?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • armedmonkey
    New Member
    • Dec 2009
    • 2

    returning a string array from function on stack?

    I need to write a function that takes a delimited string and produces an array of strings (just like string.Split() in C#).

    Is there a way to allocate this array on the stack so that the caller does not have to worry about freeing each pointer?

    I'm using GCC C and only have access to standard libraries.

    I am a novice in C, but I understand that stack space is quite limited. These arrays should be on the short side as they just contain unix paths.

    The reason I am trying to do this is
    a) because the code would look cleaner without having the free code in the caller
    b) i'm doing this for a class, and the professor specified:

    parse path – split into array of strings. (if you allocate memory here, be sure to free it before you return)

    which is not really a requirement, but made me wonder how this is accomplished because as I understand it to accomplish this you have to use strtok and allocate a copy of each string onto the heap, copying and enlarging your array when you reach capacity.
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    OK whether stack space is limited or not is actually implementation defined. For instance on windows stack space is normally not very limited at all since it can grow. However on many platforms stack space is limited and I would say it is best practice to treat stack space as though it were limited.

    You can not do what you describe on the stack using basic types (you could do it with a class) because what you describe requires a array of pointers that can increase in size (and presumably the pointers have to pointer to varying sizes of data). The size of what is allocated on the stack is generally fixed at compile time so anything that changes data size at run time can not be on the stack.

    Comment

    • donbock
      Recognized Expert Top Contributor
      • Mar 2008
      • 2427

      #3
      Are you using C or C++?

      In C there are only a few options:

      1. The function can malloc space for the fragment strings plus the array of points. It is the caller's responsibility to free this memory when done with it. Sounds like you are trying to avoid this option.

      2. The caller can pass the necessary memory to the function. This can be either automatic [stack] variables or malloc'ed by the caller. If the latter then the caller is still responsible for freeing the memory. If this option is chosen then the function ought to be able to signal an error to the caller if the provided memory isn't big enough.

      3. The caller and function can share access to file-scope variables (either static or extern). This approach is usually considered ... inelegant. It is also not thread-safe.

      Here's an example of option 2 using automatic variables:
      Code:
      #define NSTRINGS 10
      #define MAX_STRING_SIZE 40
      ...
      void caller(void)
      {
         ...
         int isFailed;
         char strings[NSTRINGS][MAX_STRING_SIZE];
         char * const array[NSTRINGS] = {
            strings[0], strings[1], strings[2], strings[3], strings[4],
            strings[5], strings[6], strings[7], strings[8], strings[9] };
         ...
         isFailed = function(..., array, NSTRINGS, MAX_STRING_SIZE);
         ...
      }
      ...
      int function(..., char * const array, int nstrings, int max_string_size)
      {
      ...
      }
      Note:
      1. Macros are sometimes necessary in C; they are never necessary and usually ill-advised in C++.
      2. Variables isFailed, strings, and array are automatic variables within function 'caller'. They disappear when 'caller' returns.
      3. Two-dimensional arrays are tricky to use correctly. The only reason I used one here is that it is a concise way to allocate several char arrays all of the same length.
      4. Strictly speaking, trickier use of the two-dimensional array could eliminate the need for the explicit array variable. In my opinion you're better off not being that tricky. Refer to Arrays Revealed to see what I'm talking about.
      5. char * const means that the contents of the strings may be changed, but the string pointers in the array cannot. That's why we need an initializer.
      6. There is no way in C for the function to infer the dimension of the array argument. You should explicitly pass the number of strings in the array and the maximum length of the strings. It is inelegant for the function to refer to the macros direclty, even though they might be in scope.

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        Originally posted by ArmedMonkey
        Is there a way to allocate this array on the stack so that the caller does not have to worry about freeing each pointer?
        Create a process private heap. Allocate from that heap rather than the CRT heap. At the end just delete the heap.

        Comment

        • armedmonkey
          New Member
          • Dec 2009
          • 2

          #5
          Thank you guys, that answers my question very well.

          Comment

          Working...