使用返回指针正确使用free是什么意思?

时间:2018-05-31 15:18:00

标签: c pointers return-value

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

#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函数中,我使用了三个char数组,我将传递给我的函数。这个函数有一个长值的num指针,其中calloc两个。然后我只是根据str[]中的内容计算一些数字并返回nums

我对此的疑问是:

  1. 如何释放我用于nums的内存?因为我在使用它之前无法释放它。
  2. 在最后一行释放retValue是否正确?
  3. 我是对的,我不需要释放我的char数组,因为它们不是动态的吗?
  4. 感谢您的回答,这将有助于我更安全地使用指针!

3 个答案:

答案 0 :(得分:9)

您需要在free的每个新作业之前致电retValue(前一作业来自malloccallocrealloc)。否则你会有内存泄漏。

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

答案 1 :(得分:3)

回答有关内存分配和使用的问题的好方法是使用内存检查器 - 我将使用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)

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

答案 2 :(得分:1)

如果你不想用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;
}