如何修复C中的“内存泄漏”

时间:2019-06-02 08:06:39

标签: c

我正在编写一个动态分配的C程序

有人可以在“ goto”中解释如何解决此内存泄漏

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>

int main()
{
    printf("start main\n");
    char *f = NULL;
    L1:
        f = (char *)malloc(10);
        if (f == NULL)
            return -1;
        printf("body lebel\n");
        f = "A";
        if (f == "B") {
            free(f);
            goto L1;
        }

      return 0;

 return 0;
} 

valgrind --leak-check=full ./a.out

输出:

==7217== HEAP SUMMARY:
==7217==     in use at exit: 10 bytes in 1 blocks
==7217==   total heap usage: 2 allocs, 1 frees, 1,034 bytes 
allocated

1 个答案:

答案 0 :(得分:1)

第一

f = "A";

将char指针f分配为指向"A",这是一个const char*,位于过程映像中的某个位置。这将完全孤立您用malloc分配的内存。要将字符串"A"复制到f指向的内存中,您需要编写类似

的内容
strcpy(f, "A");

strncpy(f, "A", 10);

警告:strcpy可能会超出您为f分配的缓冲区,而strncpy可能会使其保留为非空值。

第二,您只能在if语句内释放f,然后再跳至L1。要在程序退出之前也释放f,还必须在free(f)之前写return 0

第三,f == "B"检查f是否指向const char *值"B",而不是其内容是否与"B"相同。在您的程序中,这始终是错误的,因为您在比较之前就将其分配给了"A"。您需要将strcmp之类的函数用于以null终止的字符串,或者将memcmp用于可能以非null终止的字符串。

还可以将第一个free移动到标签的开头,这样就不必确保在跳转之前将其释放,因为free(NULL)不会这样做任何东西。同样出于后代的利益,您应该将"A""B"声明为变量,并将常量10移动到变量中,以防止将来发生内存冲突:

int main()
{
    const char a_str[] = "A";
    const char b_str[] = "B";
    size_t buffer_size = 10;
    printf("start main\n");
    char *f = NULL;
    L1:
        free(f);
        f = (char *)malloc(buffer_size);
        if (f == NULL)
            return -1;
        printf("body lebel\n");
        if (buffer_size < sizeof(a_str)) {
            printf("Buffer too small for %s\n", a_str);
            exit(1);
        }
        memcpy(f, a_str, sizeof(a_str));
        if (buffer_size < sizeof(b_str)) {
            printf("Buffer too small for comparison with %s\n", b_str);
            exit(1);
        }
        if (!memcmp(f, b_str, sizeof(b_str)) {
            goto L1;
        }
    free(f);

    return 0;
}