首页 > 解决方案 > 如何修复 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

标签: c

解决方案


第一的

f = "A";

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

strcpy(f, "A");

或者

strncpy(f, "A", 10);

警告strcpy可能会超出您分配的缓冲区fstrncpy可能使其非空终止。

其次,f在跳转到L1. 要f在程序退出之前释放,您还必须编写free(f)before return 0

第三,f == "B"检查是否f指向 const char* 值"B",而不是其内容是否与"B". 在您的程序中,这始终是错误的,因为您"A"在比较之前将其分配给它。您需要对strcmp以空字符结尾的字符串或memcmp可能以非空字符结尾的字符串使用类似函数。

也可以将第一个移动free到标签的开头,这样您就不必确保在跳跃之前释放它,因为free(NULL)它不会做任何事情。同样为了后代的利益,您应该将"A"and声明"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;
}

推荐阅读