c - 如何修复C中的 ‘memory leak’

标签 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

最佳答案

第一

f = "A";

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

strcpy(f, "A");

strncpy(f, "A", 10);

需要注意的是,strcpy 可能会超出为 f 分配的缓冲区,而 strncpy 可能会使其非空终止。

其次,在跳转到 L1 之前,您只需释放 if 语句内的 f 即可。要在程序退出之前释放 f,您还必须在 return 0 之前编写 free(f)

第三,f == "B" 检查f是否指向 const char* 值"B",而不是其内容是否指向与“B”相同。在您的程序中,这始终为 false,因为您在比较之前将其分配给 "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;
}

关于c - 如何修复C中的 ‘memory leak’,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56413274/

相关文章:

c - C语言中如何遍历二维数组对角线?

c - 如何选择数组中的给定数据?

c - 在 2d 数组 3x3 幻方中查找重复值

c - 仅使用按位运算符实现逻辑非(除了!)

c - 是否可以从 FILE* 中拯救文件描述符?

CTRL+C 和 CTRL+Z 信号在 C 中不会被阻塞

c - C89、C90 或 C99 中的所有函数都需要原型(prototype)吗?

c - 如何仅使用一个函数 showCnt() 来显示结构体数组的成员?如何传递参数?

c - 从 Node.js 访问 C 函数

c - 在C中获取帧指针