Reputation: 2571
OK, the following way to return a string works fine:
char* SU(double V) {
static char Str[80];
// Do something
return Str;
}
printf("%s", SU(A));
But the following will fail silently because the string space in memory is the same at the end of both calls:
printf("%s %s", SU(A), SU(B));
How can I do this cleanly and simply ? I was looking at alloca() but I don't think I can return a string allocated with alloca(), can I ?
Upvotes: 0
Views: 212
Reputation: 14452
Effectively, all current C compilers support compound literals and inline functions. Together it is possible to write thread-safe, memory-safe implementation that does not rely on static buffers (that can lead to unexpected bugs).
Basic idea is to combined a function that uses caller provided buffer, with a macro to abstract the creation of this temporary buffer. Negligent performance/memory impact for most applications.
For example - for the case of return the string-ified version of the a number the following itoa function can be implemented with macro/wrapper/inline function.
The limitation is that the wrapper need a way to estimate the size of returned string.
#include <stdio.h>
const char *itoa_wrapper(char *buffer, int buffer_sz, int val)
{
int result = snprintf(buffer, buffer_sz, "%d", val) ;
// Assuming formatting always works
return buffer ;
}
#define itoa(val) itoa_wrapper( (char[20]) {}, 20, val)
int main(int argc, char **argv)
{
printf("ARGC=%s, 1+2+3+4=%s\n", itoa(argc), itoa(1+2+3+4)) ;
}
Upvotes: 1
Reputation: 2571
In addition to the perfectly valid solutions you have proposed, I thought about a different approach which can be applied in this case, since the objective was to feed the returned strings to printf: it's to use the GNU C register_printf_function function to add custom format strings to printf.
More info here and an example here for MAC addresses
Upvotes: 0
Reputation: 36082
Change your function to allocate a string on the heap instead.
char* SU(double V) {
char* Str = malloc(80);
// Do something
return Str;
}
don't forget to free the returned string once you are done with it.
char* a = SU(A);
char* b = SU(B);
printf("%s %s", a, b);
free(b);
free(a);
Upvotes: 1
Reputation: 213872
It is always best to leave allocation to the caller. The standard way to return strings from functions in C is through parameter:
void SU (double V, char* str, size_t size);
Or in modern C you could do:
void SU (double V, size_t size, char str[static size]);
(See this)
Upvotes: 3
Reputation: 40829
Serialise the calls to SU
:
printf("%s ", SU(A));
printf("%s" , SU(B));
Alternatively, copy the returned strings:
char *sua = strdup(SU(A));
char *sub = strdup(SU(B));
printf("%s %s", sua, sub);
free(sua);
free(sub);
Upvotes: 2