找出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