Search code examples
cdynamicinitializationvalgrindrealloc

C - matrix realloc and uninicialized values


I have have matrix that is dynamically allocated depending on the input. One line of input is one row in the matrix. Allocation ends with the EOF. The problem is, if I enter more than one row, valgrind show this. I really dont know what is wrong.

==6142== Conditional jump or move depends on uninitialised value(s)
==6142==    at 0x402C5F9: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==6142==    by 0x80488F4: reallocMe (in /home/jan/NetBeansProjects/PA1/pokus)
==6142==    by 0x80493CC: readMatrix (in /home/jan/NetBeansProjects/PA1/pokus)
==6142==    by 0x804962A: main (in /home/jan/NetBeansProjects/PA1/pokus)
==6142==  Uninitialised value was created by a heap allocation
==6142==    at 0x402C63E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==6142==    by 0x80488A4: reallocMe (in /home/jan/NetBeansProjects/PA1/pokus)
==6142==    by 0x80493CC: readMatrix (in /home/jan/NetBeansProjects/PA1/pokus)
==6142==    by 0x804962A: main (in /home/jan/NetBeansProjects/PA1/pokus)

There is the reallocMe() function

int ** reallocMe(int ** resultsMatrix, int rows, int cols) {
    int i;

    resultsMatrix = (int **) realloc(resultsMatrix, sizeof(*resultsMatrix)*rows);
    if(!resultsMatrix)
        return NULL;

    for(i = 0; i < rows; i++) {
        resultsMatrix[i] = (int *) realloc(resultsMatrix[i], sizeof(*resultsMatrix[i])*cols);
        if(!resultsMatrix[i]) {
            freeMatrix(resultsMatrix, i);
            return NULL;
        }

    }

    return resultsMatrix;
}

And there is the readMatrix() function where I call reallocMe()

int ** readMatrix(int ** matrix, int * rows, int * cols, int * matrixSum) {
    int number;
    char delimiter;
    int numbersCount = 0;
    int delimitersCount = 0;
    int breaker = 0;
    int actualCol = 0;
    int ** test;

    printf("Enter the matrix:\n");

    while (1) {
        if (scanf("%d", &number) != 1) break;
        numbersCount++;

        if(number <= 0) breaker = 1;

        if (*rows == 1)
            *cols = *cols +1;

        /* Memory allocation */ 
        test = reallocMe(matrix, *rows, *cols);
        if(!test) {
            freeMatrix(matrix, *rows);
            return NULL;
        }

        matrix = test;

        matrix[*rows-1][actualCol] = number;
        *matrixSum += number;
        actualCol++;

        if (scanf("%c", &delimiter) == 1 && delimiter == ',') {
            delimitersCount++; 

        } else if(iscntrl(delimiter)) {

            if ((actualCol > *cols) && (*rows > 1)) { /* if the count of columns is not same on every row, then break */
                freeMatrix(matrix, *rows);
                return NULL;
            }            

            if((*rows * *cols)-*rows != delimitersCount) {
                freeMatrix(matrix, *rows);
                return NULL;
            }

            actualCol = 0;
            *rows = *rows + 1;        
        } else {
            freeMatrix(matrix, *rows);
            return NULL;
        }
    }


    *rows = *rows - 1;

    if (!feof(stdin)) {
        freeMatrix(matrix, *rows);
        return NULL;
    }
    if(*rows * *cols != numbersCount) {
        freeMatrix(matrix, *rows);
        return NULL;
    }

    if(breaker == 1) {
        freeMatrix(matrix, *rows);
        return NULL;
    }

    if(*rows * *cols == 1) {
        freeMatrix(matrix, *rows);
        return NULL;    
    }

    return matrix;
}

I dont know how to fix this. Can anyone give me some advice, hint, whatever? Thanks :)


Solution

  • realloc doesn't zero new memory. So the loop that allocates memory per row is incorrect for the new rows.

    To fix that, you should either zero all pointers to new (added) rows before the loop, or run the realloc loop for old rows only, and using malloc for the new ones.