从没有malloc的函数返回字符串

ble*_*fee 19 c malloc pointers

是否可以在不调用的情况下从函数返回字符串malloc?我有如下功能:

char* getString(){
      char tempStr[20]

      // open file, read char by char and assign to tempStr
      // ....

      char* str = (char*)malloc(sizeof(char)*20);
      strcpy(str, tempStr); // assume this copy the null terminating char as well
      return str;
}
Run Code Online (Sandbox Code Playgroud)

然后当我调用时getString(),我将返回值赋给a char*,然后在完成后将其释放,如下所示:

void randomFunction(){
      char* line = NULL;
      int i = 0;
      while (i < 1000) {
           line = getString();
           // do stuff with line
           free (line);  
           line = NULL;
      }
}
Run Code Online (Sandbox Code Playgroud)

但是,我想知道有没有办法做到这一点没有malloc?而且,这是从C函数返回字符串的正确方法吗?我试着做一些关于如何没有返回的研究malloc,但没有找到明确的答案.我是C的新手,还在学习.

izo*_*ica 12

您不能从函数返回临时值,除非使用malloc,否则函数中定义的字符数组将是临时的.一种替代解决方案是将字符数组作为参数传递给函数,并将其用作输出参数.

  • 如果调用者以特定大小声明了数组,则可以避免使用malloc. (2认同)

Kei*_*son 12

从函数返回字符串有三种常用方法.(嗯,实际上没有,但有三种常用方法可以返回指向字符串的指针,然后调用者可以使用它来访问字符串.)

  1. 使用malloc()函数内部为字符串分配空间.这是最灵活的方法,但它使调用者负责free()分配的数组.它还会带来一些性能开销.

  2. 要求调用者为字符串分配空间并传入指向该空间的指针.这给呼叫者带来了一些不便.特别是,调用者必须决定字符串的大小.

  3. 返回指向static函数内定义的数组(的第一个元素)的指针.函数返回后,数组将继续存在,但只有一个副本,这意味着连续的调用将破坏先前调用返回的结果.这也意味着数组必须具有一定的固定大小,在编写代码时选择.


Bas*_*tch 8

这取决于.

您可以决定并记录返回的字符串是指向某个静态内部缓冲区的指针.那么你的例程就不是可重入的(也不是线程安全的).例如ctimegetpwent那样做.

更好的方法是将结果字符串和大小作为参数传递,并填充该字符串并可能返回该字符串.getcwd(或snprintfstrftime返回一个大小,而不是一个指针)工作的方式.

但通常,您决定并记录返回的字符串是堆分配的,并且调用者free对其负责.你可能想要使用strdupasprintf在那种情况下.

你可以在你的整个程序中使用Boehm的保守垃圾收集器(例如使用它GC_STRDUPGC_MALLOC_ATOMIC用于字符串,以及GC_MALLOC包含一些指针的堆值.)

如果您觉得标准mallocstrdup太慢(但请先测量一下),您可以拥有自己的池分配器等.

您也可以使用备用方案(但记录它们很重要).例如,您可以返回一些实习字符串,甚至是规范实习字符串(有时称为"夸克"或"符号") - 然后能够使用指针相等而不是字符串相等.你也可以有一些参考计数器方案.例如,在什么Glib(来自GTK,但可以在GUI程序之外使用!)提供:GString-s,GQuark-s,字符串实用程序

然而,重要的是确定结果是否是堆分配的,并且明确定义谁有责任释放(以及如何释放)堆分配的结果.

您可能希望使用valgrind来追踪内存泄漏.别忘了传递-Wall -g给你的gcc编译器!

PS.我会考虑使用Boehm的GC.而且我不认为malloc(或者strdup,asprintf....)应该是性能方面的原因拒绝了(你可以选择一些其他的和更快malloc的实现,或者使用自己的内存池).但是,内存泄漏可能是个问题.