C函数返回一个字符串



我试图在C中创建一种toString函数,如下所示:

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;
}

并以这种方式在main中使用:

printf("%s", esploratoreToString(e));

它是有效的,但问题是:malloc分配的内存会被释放吗?

这是唯一的解决方案吗?

char *s = esploratoreToString(e);
...
printf("%snn", s);
free(s);

在原始代码中,内存不会被释放。这是内存泄漏。

要正确调用此函数,您必须执行

char *s = esploratoreToString(e);
printf("%s", s);
free(s);

如果要让esploratoreToString进行分配,那么实际上没有任何方法可以解决这个问题。C中动态分配的对象永远不会释放自己。(C++是另一回事…(

(当然,esploratoreToString应该在继续之前检查malloc是否成功…(

是。这是C中常见的习惯用法:被调用者分配内存,将所有权转移给调用者。这意味着调用者现在负责释放分配的块。

malloc()分配的内存在调用free()时释放,否则在进程退出时将释放。作为目前的设计,调用代码负责在使用完内存后释放内存。或者,您可以重新设计exploratoreToString(),以提供缓冲区及其大小作为参数。

有一种替代方案,您可以在其中提供缓冲区:

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("%sn", esploratoreToString(&exp, buf, sizeof buf);
}

因此,您可以动态地分配它,或者作为一个自动堆栈分配的缓冲区。

另一种选择是返回一个指向静态分配的缓冲区的指针,如:

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;
}

但这有一个问题,即它是不可重入的,而且如果你需要在对printf(3)的同一次调用中调用它两次(在main中(,第二次调用将覆盖缓冲区,并且你会得到一个奇怪的行为,因为用下一个结果覆盖一个结果,并打印两次相同的东西。

相关内容

  • 没有找到相关文章

最新更新