Search code examples
arrayscmemorydynamicvalgrind

Use of uninitialised value of size 8 from valgrind in c


As Valgrind gives line numbers in the error summary, I'll provide the complete code:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int n = 0;
int q = 0;
int Z = 0;
scanf("%i %i", &n, &q);
fgetc(stdin);
int seqList[n][n];
int lastAnswer = 0;
char *queries[q];
int *index = malloc((sizeof(int) * n));          // Line 14
int *last = malloc(sizeof(int) * q);
int k = 0;
for (int i = 0; i < q; i++)
{
    queries[i] = malloc(sizeof(char) * 6);
    scanf("%[^\n]%*c", queries[i]);

    if (queries[i][0] == '1')
    {
        int x = queries[i][2] - '0';
        int y = queries[i][4] - '0';
        int z = (x ^ lastAnswer) % n;
        Z = *(index + z);
        seqList[z][Z] = y;                       // Line 27
        *(index + z) = Z + 1;
    }
    else if (queries[i][0] == '2')
    {
        int x = queries[i][2] - '0';
        int y = queries[i][4] - '0';
        int z = (x ^ lastAnswer) % n;
        Z = *(index + z);
        lastAnswer = seqList[z][y % Z]; //floating point exception
        last[k] = lastAnswer;
        k++;
    }
    free(queries[i]);
}
for (int i = 0; i < k; i++)
{
    printf("%i\n", last[i]);
}
free(last);
free(index);
}

When I run the program, on my second input (after providing the values of n and q), I get this error message:

==9541== Use of uninitialised value of size 8
==9541==    at 0x4008FA: main (dynamic.c:27)
==9541==  Uninitialised value was created by a heap allocation
==9541==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind    /vgpreload_memcheck-amd64-linux.so)
==9541==    by 0x40080B: main (dynamic.c:14)
==9541== 

Lines 27 and line 14 are highlighted with with comments; I tried implementing this in many ways but couldn't understand what it means by the "uninitialized" value.


Solution

  • In the following line(s):

        Z = *(index + z);
    

    you are, on at least one occasion, reading a value from the index memory block that has not yet had a value assigned to it. (Incidentally, you can use Z = index[z] for clearer code.) So, the value of that 'array element' will be uninitialized.

    I'm not sure what initial values you want/need to assign to that index array but, as suggested in the comments, you can use the calloc() function to set all elements to zero at the time of allocation (note that the malloc() function creates a block of uninitialized data).

    So, instead of:

    int* index = malloc((sizeof(int) * n));
    

    use:

    int* index = calloc(n, sizeof(int));