在C中的循环中重写全局字符数组与全局字符指针



我有一个无限while循环,我不确定我应该使用char数组还是char指针。该值不断被覆盖并在其他函数中使用。对于char指针,我知道可能存在内存泄漏,那么使用数组更可取吗?

char *recv_data = NULL;
int main(){
.....
while(1){
.....
recv_data = cJSON_PrintUnformatted(root);
.....

}
} 

char recv[256] = {0};
int main(){
.....
while(1){
.....
strcpy(recv, cJSON_PrintUnformatted(root));
.....

}
} 

应该首选第一个版本。

  1. 它对返回字符串的大小没有限制
  2. 您可以使用free(recv_data)来修复内存泄漏

第二个版本有以下错误功能:

  1. 函数返回的内存无法释放,因为您从未将其分配给可以传递给free()的变量
  2. 它的效率有点低,因为它执行不必要的复制

根据您的使用方式,cJSON_PrintUnformatted返回一个指向char数组的指针。由于没有输入参数,它可能会动态地分配函数内部的内存。你可能需要free那个内存。因此,您需要返回的指针,以便自己释放内存。

第二个选项会丢弃返回的指针,因此您失去了释放已分配内存的唯一方法。因此,它将保持分配->memroy泄漏。

当然,这一切都取决于功能是如何实现的。也许它只是操纵一个全局数组并返回一个指向它的指针,所以没有必要释放它

正如@Barmar所指出的,第二个版本确实存在内存泄漏。

然而,即使您要修复内存泄漏,您仍然不能真正使用代码的第一个版本:对于第一个版本,您必须在编译时决定cJSON_PrintUnformatted()返回的字符串的最大长度。现在,

  • 如果您选择的值太低,strcpy()函数将超出数组界限并损坏堆栈
  • 如果你选择的值太高以至于安全,你可能不得不超过程序堆栈的可用空间量,从而导致堆栈溢出(是的,就像这个网站的名称一样)。您可以使用strncpy()来修复这个问题,给出最大大小,然后得到一个截断的字符串

因此,除了使用cJSON_PrintUnformatted()的返回值所指向的任何内存(可能是堆分配的内存)之外,您真的没有太多选择。另外,既然它已经在那里供你使用,为什么还要复制它呢?懒惰:-)

PS-对于cJSON_PrintUnformatted()来说,真正应该做的是将缓冲区和缓冲区大小作为参数,让它的调用者对内存分配和资源限制有更多的控制权。