【问题标题】:Why does valgrind not show the obvious leaks in my program? [closed]为什么 valgrind 没有在我的程序中显示明显的泄漏? [关闭]
【发布时间】:2021-01-25 18:34:41
【问题描述】:

当我编译一个使用 malloc 两次的程序时,我意识到我忘记在程序结束时释放分配的内存。

最近遇到了 Valgrind 工具,我认为这是一个运行它以查看它如何显示内存泄漏错误的好时机。但令我惊讶的是,Valgrind 返回所有堆块都已释放...

Valgrind results

我唯一能想到的是 malloc 不在主函数中,而是在从属函数中。但我不认为 Valgrind 会被限制在 main 上,不是吗

我试图在 Valgrind 文档中找到答案,但无济于事。

这是所要求的完整代码,其目的是通过用户作为命令行参数提供的 26 个字母的密钥来加密文本。

#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

void cipher(char *, char *);

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("Usage: ./substitution key\n");
        return 1;
    }

    //INPUT
    char *p = get_string("plaintext: ");

    //OUTPUT
    cipher(argv[1], p);
    return 0;
}

void cipher(char *a, char *b)
{
    char *low = malloc(27 * sizeof(char));
    for (int i = 0; i < 27; i++)
    {
        if (islower(a[i]))
        {
            low[i] = a[i];
        }
        else
        {
            low[i] = (a[i] + 32);
        }
    }

    char *upp = malloc(27 * sizeof(char));
    for (int i = 0; i < 27; i++)
    {
        if (isupper(a[i]))
        {
            upp[i] = a[i];
        }
        else
        {
            upp[i] = a[i] - 32;
        }
    }

    printf("ciphertext: ");

    for (int i = 0, l = strlen(b); i < l; i++)
    {
        if (islower(b[i]))
        {
            printf("%c", low[(int)b[i]-97]);
        }
        else if (isupper(b[i]))
        {
            printf("%c", upp[(int)b[i]-65]);
        }
        else
        {
            printf("%c", b[i]);
        }
    }
}

【问题讨论】:

  • 你使用了哪些命令行参数来调用 valgrind?
  • 编辑您的问题并发布所有您的代码。从您所做 发布的内容来看,您应该 有泄漏。我合成了你程序的其余部分,你确实有一个内存,valgrind 报告 [here]:definitely lost: 64 bytes in 3 blocks 另外,这似乎是cs50get_string 返回的指针是分配,所以你也需要free旁注:这有点没有意义,因为更好的设计可以用char upp[27];char low[27];替换upplow,消除malloc
  • 同意,这需要minimal reproducible example。例如,编译器优化可能导致 malloc 实际上没有被某些输入调用。我们需要完整的源代码、使用的准确输入、编译器版本和选项以及 valgrind 选项。
  • 对于您的问题,不,valgrind 不限于main,并且应该跟踪和报告所有malloc 分配的泄漏,无论是什么功能。
  • 将图像中可见的线条粘贴为文本而不是图像会改善问题

标签: c malloc valgrind free cs50


【解决方案1】:

在所有这些 cmets 之后,答案有点傻......

您的屏幕截图显示您运行了valgrind ./substitution,而没有将任何命令行参数传递给您的程序。发生这种情况时,它会打印 Usage: ./substitution key 并退出而不做任何进一步的事情;特别是没有调用cipher(),因此也没有调用malloc()。所以在这种情况下当然没有内存泄漏。

如果您在命令行中使用 key 参数运行程序,并给它一些输入,您应该会看到 valgrind 报告内存泄漏:

==15815== 
==15815== HEAP SUMMARY:
==15815==     in use at exit: 54 bytes in 2 blocks
==15815==   total heap usage: 4 allocs, 2 frees, 2,102 bytes allocated
==15815== 
==15815== LEAK SUMMARY:
==15815==    definitely lost: 54 bytes in 2 blocks
==15815==    indirectly lost: 0 bytes in 0 blocks
==15815==      possibly lost: 0 bytes in 0 blocks
==15815==    still reachable: 0 bytes in 0 blocks
==15815==         suppressed: 0 bytes in 0 blocks
==15815== Rerun with --leak-check=full to see details of leaked memory

虽然原则上编译器可以优化 malloc 调用,但在我使用 gcc 和使用 -O3 进行的测试中,我找不到任何迹象表明他们确实这样做了。

【讨论】:

  • 天哪,愚蠢确实是描述我的感受的正确词。我想这一切让我意识到了优化编译器的概念,这是我以前从未听说过的,所以一切都没有丢失。我显然太新手了,无法在这个网站上表现出某种形式的欣赏,如果它不符合当地规则,我会明白的,但我知道我对那些花了一些时间来解决这个问题的人的感受。
猜你喜欢
  • 2016-01-02
  • 1970-01-01
  • 1970-01-01
  • 2019-07-17
  • 2013-03-28
  • 1970-01-01
  • 1970-01-01
  • 2016-07-11
  • 2021-06-27
相关资源
最近更新 更多