c-解决valgrind提出的问题



我试图通过分配所需内存加1并将最后一个元素设置为-1来获得C中整数数组的大小。然后我创建一个名为getSize的函数来确定数组中这个-1元素之前的元素数量,这是代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int getSize(int * array)                                                        
{                                                                               
    int i=0;                                                                    
    while(1)                                                                    
    {                                                                           
        if(array[i] ==  -1) return i;                                           
        else i++;
    }
}
int main()
{
    int * array = malloc(sizeof(int)*5);
    memset(array,0,5);
    array[4] = -1;
    printf("nsize = %dn",getSize(array));
    return 0;
}

这只是一个测试代码,但函数getSize是更大代码的一部分,我在这个代码上运行了valgrind,这就是我遇到的问题:

===1683===条件跳转或移动取决于未初始化的值
===1683===在0x100000EAE:getSize(in./a.out)
===1683===通过0x100000F2E:主(输入/输出)

总结如下:

===1683===健康总结:
===1683===出口使用中:425个块中有38676个字节
===1683===总堆使用率:508个分配,83个释放,44948个字节分配

泄漏总结:
===1683===肯定丢失:2个块中有36个字节
===1683===间接丢失:0个块中有0个字节
===1683===可能丢失:119个块中有13130个字节
===1683===仍然可访问:304个块中有25510个字节
===1683===已抑制:0个块中有0个字节
===1683===错误摘要:20个上下文中的22个错误(抑制:0到0)

这段代码中有几个问题。您展示的valgrind输出突出了两个问题。

===1683===条件跳转或移动取决于未初始化的值
===1683===在0x100000EAE:getSize(in./a.out)
===1683===通过0x100000F2E:主(输入/输出)

这是由getSize()中的if语句触发的

if(array[i] ==  -1) return i;  

乍一看,这似乎还不错;在主函数中,使用malloc分配内存,然后使用memset将其清零,然后将最后一个元素设置为-1。

然而,让我们仔细看看

    int * array = malloc(sizeof(int)*5);
    memset(array,0,5);

您已经分配了足够大的空间来容纳5个整数,很可能是20个字节。然后尝试对其进行memset,但是memset当时对一个字节进行操作——换句话说,大小应该是以字节为单位的长度,而不是整数。所以,在这个操作之后,你得到了0’d的5个字节。内存的其余部分仍未初始化。

接下来使用数组表示法将最后一个整数设置为-1。这意味着您有一个20字节的缓冲区,前5个和后4个字节已初始化。

回到getSize函数,for循环中的第一次迭代很好,但第二次、第三次和第四次迭代读取未初始化的字节,并在此基础上执行条件跳转。

我们在valgrind输出中看到的第二个错误是内存泄漏。

泄漏总结:
===1683===肯定丢失:2个块中有36个字节
===1683===间接丢失:0个块中有0个字节
===1683===可能丢失:119个块中有13130个字节
===1683===仍然可访问:304个块中有25510个字节
===1683===已抑制:0个块中有0个字节
===1683===错误摘要:20个上下文中的22个错误(抑制:0到0)

在"绝对丢失"部分,它告诉我们您在2个块中丢失了36个字节。实际上,您提供的代码中只有一个漏洞,那就是为array分配的内存。您需要添加以下行:

free(array);

在结束您的功能返回之前。Valgrind可以为您提供更多关于内存泄漏的详细信息——请在输出中查找提示。

相关内容

  • 没有找到相关文章

最新更新