我试图通过分配所需内存加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 = %d\n",getSize(array));
    return 0;
}

这只是一个测试代码,但函数getSize是更大代码的一部分,我在这段代码上运行了valgrind,这就是我遇到的问题:
==1683==条件跳转或移动取决于未初始化的值
==1683==at 0x100000EAE:getSize(in./a.out)
==1683==by 0x100000F2E:main(输入/输出)
总结如下:
==1683==堆摘要:
==1683==在退出时使用:在425个块中有38676个字节
==1683==堆使用总量:508个分配,83个释放,44948个分配字节
泄漏摘要:
==1683==绝对丢失:两个块中36个字节
==1683==间接丢失:0块中的0字节
==1683==可能丢失:119块中13130字节
==1683==仍然可以访问:304块中的25510字节
==1683==抑制:0块中的0字节
==1683==ERROR SUMMARY:20个上下文中的22个错误(不显示:0中的0)

最佳答案

这段代码中有几个问题您显示的valgrind输出突出显示了两个问题。
==1683==条件跳转或移动取决于未初始化的值
==1683==at 0x100000EAE:getSize(in./a.out)
==1683==by 0x100000F2E:main(输入/输出)
这是由getSize()中的if语句触发的

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

乍一看似乎应该没问题;在主函数中,在将最后一个元素设置为-1之前,您使用malloc分配内存,然后使用memset将其归零。
不过,让我们仔细看看
    int * array = malloc(sizeof(int)*5);
    memset(array,0,5);

您分配的空间足够容纳5个整数,所以可能是20个字节然后尝试memset,但是memset在一个字节上操作-换句话说,大小应该是字节长度,而不是整数。
所以,在这个操作之后,5个字节的值为零其余内存仍未初始化。
接下来,使用数组表示法将最后一个整数设置为-1这意味着您有一个20字节的缓冲区,前5个字节和后4个字节初始化。
回到getSize函数,for循环中的第一次迭代是可以的,但是第二次、第三次和第四次迭代读取未初始化的字节,并基于此执行条件跳转。
我们在valgrind输出中看到的第二个错误是内存泄漏。
泄漏摘要:
==1683==绝对丢失:两个块中36个字节
==1683==间接丢失:0块中的0字节
==1683==可能丢失:119块中13130字节
==1683==仍然可以访问:304块中的25510字节
==1683==抑制:0块中的0字节
==1683==ERROR SUMMARY:20个上下文中的22个错误(不显示:0中的0)
在绝对丢失部分,它告诉我们您在两个块中丢失了36个字节实际上,您提供的代码中只有一个漏洞,那就是为array分配的内存您需要添加以下行:
free(array);

在从你的工作岗位回来之前Valgrind可以为您提供关于内存泄漏的更多细节-在输出中查找提示。

关于c - 找出valgrind提出的问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28334344/

10-11 23:13