Figuring out issues raised by valgrind

I am trying to get size of an integer array in C by allocating required memory plus 1 and setting the last element to -1. I then create a function called getSize to determine the number of elements before this -1 element in an array, here's the code

#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;
}

This is a just a test code but the function getSize is part of much bigger code, I ran valgrind on this code, this the issue I am getting:

==1683== Conditional jump or move depends on uninitialised value(s)
==1683== at 0x100000EAE: getSize (in ./a.out)
==1683== by 0x100000F2E: main (in ./a.out)

Here's the summary:

==1683== HEAP SUMMARY:
==1683== in use at exit: 38,676 bytes in 425 blocks
==1683== total heap usage: 508 allocs, 83 frees, 44,948 bytes allocated

LEAK SUMMARY:
==1683== definitely lost: 36 bytes in 2 blocks
==1683== indirectly lost: 0 bytes in 0 blocks
==1683== possibly lost: 13,130 bytes in 119 blocks
==1683== still reachable: 25,510 bytes in 304 blocks
==1683== suppressed: 0 bytes in 0 blocks
==1683== ERROR SUMMARY: 22 errors from 20 contexts (suppressed: 0 from 0)


There are several problems in this code. The valgrind output you have shown highlights two issues.

==1683== Conditional jump or move depends on uninitialised value(s)
==1683== at 0x100000EAE: getSize (in ./a.out)
==1683== by 0x100000F2E: main (in ./a.out)

This is triggered by the if statement in getSize()

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

This seems at first glance as if it should be fine; in the main function you allocate memory using malloc, and then zero it using memset, before setting the last element to -1.

However, lets take a closer look

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

You have allocated space large enough to hold 5 integers, so likely 20 bytes. You then attempt to memset this, however memset operates on a byte at the time - in other words the size should be the length in bytes, not integers. So, after this operation, you have zero'd the 5 bytes. The rest of the memory is still uninitialized.

Next you use array notation to set the last integer to -1. This means you have a 20-byte buffer, with the first 5 and last 4 bytes initialized.

Going back to your getSize function, the first iteration in the for loop is fine, however the second , third and fourth iterations are reading uninitilized bytes, and performing a conditional jump based on this.

The second error we can see in the valgrind output is that you have leaked memory.

LEAK SUMMARY:
==1683== definitely lost: 36 bytes in 2 blocks
==1683== indirectly lost: 0 bytes in 0 blocks
==1683== possibly lost: 13,130 bytes in 119 blocks
==1683== still reachable: 25,510 bytes in 304 blocks
==1683== suppressed: 0 bytes in 0 blocks
==1683== ERROR SUMMARY: 22 errors from 20 contexts (suppressed: 0 from 0)

In the definitely lost section, it is telling us you have lost 36 bytes in 2 blocks. There is actually only one leak in the code you presented, which is the memory allocated for array . You need to add this line:

free(array);

before returning from your function. Valgrind can give you more details on memory leaks - look for the hints in the output.

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

上一篇: 抑制文件过于普遍?

下一篇: 找出valgrind提出的问题