Reputation: 21
I tried to create a sort of toString
function in C like this:
struct esploratore {
char nome[20];
char cognome[20];
int nascita;
int morte;
};
char *esploratoreToString(esploratore e) {
char *s = (char*) malloc(50 * sizeof(char));
snprintf(s, 50,
"%s %s %d %d",
e.nome, e.cognome, e.nascita, e.morte);
return s;
}
and use it in main
this way:
printf("%s", esploratoreToString(e));
it works, but the problem is: will the memory assigned by the malloc be ever freed?
is this the only solution?
char *s = esploratoreToString(e);
...
printf("%s\n\n", s);
free(s);
Upvotes: 1
Views: 78
Reputation: 12668
There's an alternative, in which you provide the buffer:
char *esploratoreToString(esploratore *e, char *buf, int bufsz) {
snprintf(buf, bufsz,
"%s %s %d %d",
e.nome, e.cognome, e.nascita, e.morte);
return buf;
}
...
int main()
{
char buf[100];
esploratore exp = {...};
printf("%s\n", esploratoreToString(&exp, buf, sizeof buf);
}
So you can allocate it dynamically, or as an automatic stack allocated buffer.
Another alternative is to returna a pointer to a statically allocated buffer, as in:
char *esploratoreToString(esploratore *e) {
static char buf[50];
snprintf(buf, bufsz,
"%s %s %d %d",
e.nome, e.cognome, e.nascita, e.morte);
return buf;
}
But this has the problem that it is not reentrant, and also if you need to call it twice in the same call to printf(3)
(in main
) the second call will overwrite the buffer and you will get a strange behaviour due to overwritting one result with the next and printing twice the same thing.
Upvotes: 0
Reputation: 1
The memory allocated by malloc()
is freed when you call free()
otherwise it will be freed when the process exits. As design right now, the calling code is responsible for freeing the memory once it's done with it. Alternatively, you could redesign exploratoreToString()
to a provide a buffer and it's size as an argument.
Upvotes: 0
Reputation: 57997
In your original code the memory will not be freed. This is a memory leak.
To call this function properly you'll have to do
char *s = esploratoreToString(e);
printf("%s", s);
free(s);
There is not really any way around this, if you are going to have esploratoreToString
do the allocation. Dynamically allocated objects in C do not ever free themselves. (C++ is another story...)
(Of course esploratoreToString
should check that malloc
succeeds before proceeding...)
Upvotes: 2
Reputation: 148880
Yes. This is a common idiom in C: the callee allocates memory and transfers ownership to the caller. That means that the caller now is responsable for freeing the allocated block.
Upvotes: 0