0

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 ?

dargaud
  • 2,431
  • 2
  • 26
  • 39
  • Possible duplicate of [Proper way to return a string in C](http://stackoverflow.com/questions/31411831/proper-way-to-return-a-string-in-c) – John Coleman Oct 20 '16 at 11:15
  • Why not allocate 2 buffers on call site and pass those to `SU`? – user694733 Oct 20 '16 at 11:17
  • Functions can allocate memory and return a pointer to this newly-allocated memory. Many programmers don't like this approach since they consider it a safer strategy to have the function which allocates memory be the function that frees it. – John Coleman Oct 20 '16 at 11:27
  • _I was looking at alloca() but I don't think I can return a string allocated with alloca(), can I ?_ . No you can't, but using `malloc` would be OK. – Jabberwocky Oct 20 '16 at 11:36

4 Answers4

3

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)

Community
  • 1
  • 1
Lundin
  • 195,001
  • 40
  • 254
  • 396
2

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);
Michael Foukarakis
  • 39,737
  • 6
  • 87
  • 123
1

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);
AndersK
  • 35,813
  • 6
  • 60
  • 86
  • Yes, that works, but that makes things complicated for the caller, which I was trying to keep simple. – dargaud Oct 20 '16 at 11:49
  • @dargaud the other way to make it less "complicated" would be to pass the Str array to the function. – AndersK Oct 20 '16 at 12:07
  • Does `static char* Str = malloc(80);` even compile??? I doubt that very much... But even if it does somehow, then I'd expect `malloc` to be invoked only once, in which case, your second call to `free` should yield undefined behavior. – barak manos Oct 20 '16 at 13:02
0

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

dargaud
  • 2,431
  • 2
  • 26
  • 39