c语言 - 返回指针的free的正确用法是什么?



>我写了一个小的例子问题来了解内存分配和释放这个内存(以防止内存泄漏(:

#include <stdlib.h>
long* foo(char str[]) {
long *nums;
nums = calloc(2,sizeof(long));
//something is happening depending on what's inside the char[]
nums[0] = 57347534;
nums[1] = 84757;
return nums;
}
int main() {
char str1[400] = "This is a test";
long* retValue = foo(str1);
//some lines of checking content of "retValue"
char str2[400] = "This is another test";
retValue = foo(str2);
//some more lines of checking content of "retValue"
char str3[400] = "This is a final test";
retValue = foo(str3);
//again some more lines of checking content of "retValue"
free(retValue);
}

因此,在我的main函数中,我使用了三个字符数组,我将传递给我的函数。此函数有一个长值的 num 指针,其中calloc其中两个。然后我只是根据str[]中的内容计算一些数字并返回nums.

我对此的问题是:

  1. 如何释放用于nums的内存?因为我在使用它返回之前无法释放它。
  2. 释放最后一行的retValue是否正确?
  3. 我不需要释放我的字符数组是对的,因为它们不是动态的?

感谢您的回答,这将有助于我更安全地使用指针!

您需要在每次新作业之前调用retValuefree(如果以前的作业来自malloccallocrealloc(。否则,您将有内存泄漏。

每个分配都必须匹配一个free,简单明了。

回答有关内存分配和使用的问题的一个好方法是使用内存检查器 - 我将使用 Valgrind:

gcc-8 -std=c11 -fPIC -g -Wall -Wextra -Wwrite-strings -Wno-parentheses -Wpedantic -Warray-bounds         50627661.c    -o 5062766
50627661.c: In function ‘foo’:
50627661.c:3:16: warning: unused parameter ‘str’ [-Wunused-parameter]
long* foo(char str[]) {
~~~~~^~~~~
valgrind -q --leak-check=full ./50627661   
==14785== HEAP SUMMARY:
==14785==     in use at exit: 32 bytes in 2 blocks
==14785==   total heap usage: 3 allocs, 1 frees, 48 bytes allocated
==14785== 
==14785== 16 bytes in 1 blocks are definitely lost in loss record 1 of 2
==14785==    at 0x4C2EBA5: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14785==    by 0x10867F: foo (50627661.c:5)
==14785==    by 0x1086F6: main (50627661.c:18)
==14785== 
==14785== 16 bytes in 1 blocks are definitely lost in loss record 2 of 2
==14785==    at 0x4C2EBA5: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14785==    by 0x10867F: foo (50627661.c:5)
==14785==    by 0x108758: main (50627661.c:24)

这表明,在我们所做的三个分配中,我们只释放了其中一个 - 另外两个泄漏了。

如果您不想用free来混淆您的调用代码,另一种方法是将调用者管理的数组传递给被调用者:

long foo(char str[], long *nums, int size) {
if (size < 2) {  // passed array must be at least 2 long
return -1;
}
//something is happening depending on whats inside the char[]
nums[0] = 57347534;
nums[1] = 84757;
return 2;   // returns used size (or -1 for error)
}
int main() {
long retValue[2];
char str1[400] = "This is a test";
if (-1 == foo(str1, retValue, 2)) {
// process error condition
}
//some lines of checking content of "retValue"
char str2[400] = "This is another test";
if (-1 == foo(str2, retValue, 2)) {
// process error condition
}
//some more lines of checking content of "retValue"
char str3[400] = "This is a final test";
if (-1 == foo(str3, retValue, 2)) {
// process error condition
}
//again some more lines of checking content of "retValue"
//free(retValue);  no need for free since nothing was allocated...
return 0;
}

最新更新