找出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 ==条件跳转或移动取决于未初始化的值(s)
== 1683 == 0x100000EAE:getSize(在./a.out中)
== 1683 == 0x100000F2E:main(在./a.out中)

总结如下:

== 1683 ==总结:
== 1683 ==在退出时使用:425个块中的38,676字节
== 1683 ==总堆使用率:508个分配,83个释放,44,948个字节分配

泄漏摘要:
== 1683 ==绝对丢失:2个块中36个字节
== 1683 ==间接丢失:0个字节0个字节
== 1683 ==可能丢失:119块中13,130字节
== 1683 ==仍然可达:304块中的25,510字节
== 1683 ==被抑制:0个字节0个字节
== 1683 ==错误摘要:来自20个上下文的22个错误(被抑制:0从0)


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

== 1683 ==条件跳转或移动取决于未初始化的值(s)
== 1683 == 0x100000EAE:getSize(在./a.out中)
== 1683 == 0x100000F2E:main(在./a.out中)

这是由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当时在一个字节上操作 - 换句话说,大小应该是以字节为单位的长度,而不是整数。 所以,在这个操作之后,你有5个字节的零。 内存的其余部分仍未初始化。

接下来使用数组符号将最后一个整数设置为-1。 这意味着你有一个20字节的缓冲区,其中前5个和后4个字节被初始化。

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

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

泄漏摘要:
== 1683 ==绝对丢失:2个块中36个字节
== 1683 ==间接丢失:0个字节0个字节
== 1683 ==可能丢失:119块中13,130字节
== 1683 ==仍然可达:304块中的25,510字节
== 1683 ==被抑制:0个字节0个字节
== 1683 ==错误摘要:来自20个上下文的22个错误(被抑制:0从0)

在绝对丢失的部分,它告诉我们你已经在2个块中丢失了36个字节。 实际上在你提供的代码中只有一个泄漏,这是为array分配的内存。 你需要添加这一行:

free(array);

在从你的函数返回之前。 Valgrind可以给你更多关于内存泄漏的细节 - 在输出中寻找提示。

链接地址: http://www.djcxy.com/p/64947.html

上一篇: Figuring out issues raised by valgrind

下一篇: stack smashing detected by valgrind