LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Return string without affect the memory

I have worked very hard on this and could not find the good way, please verify the following function:

char *string_return(char *str_src)
{
 char * strRet;
  
 str_ret = calloc(100, sizeof(char));
 
 strcpy (str_ret, str);

 return str_ret;
}
 
In this case, I want to use the content of *str to do some thing for the strRet  (but not affect the str_src), but to do that I have to use calloc or malloc for str_ret.
 
When complete to protect the memory leak ... I have to free it before return ... then now I can not return the strRet
 
*) Is there a way to fulfil the above function?
 
Many thanks
0 Kudos
Message 1 of 9
(3,798 Views)

One way to avoid the problem of calloc/free within your function is to reserve the memory at the main() level of your code, either by a single calloc() at the beginning and free() at the end, or even by creating a static array with: char string2 [100]; at the outermost level of your program. This way your function could just access string2 directly.

Not the most elegant solution and not suitable for multi-threaded operation, but it should be good enough for simple programs, as long as you know the maximum array size beforehand.

JR

 

0 Kudos
Message 2 of 9
(3,794 Views)

I am not sure that your suggestions will fix my question:

1. If I calloc/free memory at the main() level ... how it affects my function? You meant str_src or str_ret?

2. If I declare char string2 [100] in my fuction  then I can not return string2 in my function

Can you specific more detail? Thanks

 

 

0 Kudos
Message 3 of 9
(3,791 Views)

It is difficult to give more detail as it depends on the construction and intention of your overall program, and what you want to do with the returned string pointers. If you call your function several times and plan to store or compare the returned values then I agree that the approach I outlined will not work. If you just call it once and process the result before calling it again then it might be suitable. I can't tell without more information.

You are right it is not a good idea to return a pointer to a local automatic variable from a function - since these variables are allocated on the stack they turn to garbage as soon as the function returns. You can return an array that is statically declared inside the function, but then we could run into the first problem again.

Can you give us some idea of how you call this function - this could lead to different suggestions.

JR

0 Kudos
Message 4 of 9
(3,785 Views)
If your function string_return needs to output a string, then typically you have two options:
 
1. The function allocates memory (using malloc or calloc) and returns the allocated memory.  In this case, any functions that call string_return must free the returned string when they are done using it.
 
2. The function takes as input a pre-allocated array of memory as well as a parameter indicating the size of that array. Your string_return function makes sure the passed array is large enough, then fills the array with the output string data.  In this case, the caller is responsible for both allocating and freeing the memory for the output string.
 
In either case, you should put comments in your code near the function declaration to clarify the caller's responsibility.
 
Hope this helps.
 
Mert A.
National Instruments
0 Kudos
Message 5 of 9
(3,777 Views)

Here how I try to do:

char *string_return(char *str_src)
{
 char * strRet;
  
 str_ret = calloc(1000, sizeof(char));
 
 strcpy (str_ret, str_src);

 strcat (str_ret, " Yes, it does, but can not free calloc for now!");
 
 return str_ret;                // to protect memory leak, we should free str_ret instead!
}

void main (void)

{

       char *str_send, *str_feedback;

      str_send = "Does it work?";     // this string will be kept throughout the program = unchange!

     str_feedback = string_return(str_send);

     printf(str_feedback);

Note: I would like to have the same result without free (str_ret) and to have the str_feedback as: "Does it work? Yes, it does ..." without affecting content of str_send!

I hope that you now have more clear pucture about my question!

0 Kudos
Message 6 of 9
(3,774 Views)
Thanks for the suggestions, however we did discussed before about problems can cause from these:
 
1. The multiple-callers will mix-up when/who will free the memory (str_ret) after calling
2. The multiple-callers can not keep track the setup of the memory & the function will have extra parameter look more complicate for simple function
 
That was why I did say I worked very hard to find the solution! But might be you are right ... it is the only way (1 of the 2 suggestions)!
 
Thanks
 
 
0 Kudos
Message 7 of 9
(3,770 Views)
I'm not sure I understand problem 1.  Every caller of string_return must call free on the returned string after every call.  Since string_return allocates a new block of memory each time it is called, the caller must free the returned memory after each call. If you are concerned with passing the allocated string up through multiple functions, this is still fine as long as you document the caller's responsibility for each function and are consistent about returning only statically or dynamically allocated memory from any particular function.
 
Another (more restrictive) option you have is to return a static array instead of a dynamically allocated one:
 
char * string_return (char *str_src)
{
   static char str_ret[MAX_STR_SIZE + 1];
   char *str_append = " Yes, it does, but can not free calloc for now!"
 
   int n = min (MAX_STR_SIZE, strlen(str_src));
   strncpy(str_ret, str_src, n);
   str_ret[n] = '\0';
 
   if (n < MAX_STR_SIZE)
   {
      n = min (n - MAX_STR_SIZE, strlen(str_append));
      strncat(str_ret, str_append, n);  // appends null character
   }
 
   return str_ret;
}
 
With the code above, the caller never has to worry about freeing the returned string.  However, this approach has several disadvantages: the function may not be able to accomodate large input strings, it may be difficult to pick a good MAX_STR_SIZE, and calling code must be done using the return string before the function is called again.  This last point is especially problematic if this code must be called from multiple threads.
 
Additionally, I would suggest that regardless of the solution you choose, you should be careful to allocate arrays of the correct size, or use size checking code like above to prevent writing beyond the end of your array.  Writing more data (via strcpy) than your array can hold can result in some truly horrible and mysterious bugs that are very difficult to diagnose and debug.
 
Mert A.
National Instruments
0 Kudos
Message 8 of 9
(3,760 Views)
1. You are right that the callers should taking care & manage the calloc/malloc in their parts! But for the safe-measure ... I was asked to do some thing and provides minimum cares for the callers
 
2. Your codes worked very well, I will imply them and I actually feel much better now.
 
Many thanks Smiley Happy
0 Kudos
Message 9 of 9
(3,752 Views)