Search code examples
pointersdebuggingmatrixmallocoverflow

Malloc calls allocate addresses already in use


Introdution

I've ran into a weird issue, I was writting the following code that requestes the user a matrix, the program asks for the size, then the elements in the matrix.

Later, I itrerate the matrix again to calculate the max and min number in each row and also the sum of the elements in the main diagonal.

I'm writting this program to translate later to assembly that is why I am using pointers for my matrix, to keep the program as closest as it will be in assembly

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


int main(){

    int rows, cols;
    int *matrix;
    int *max, *min, diag, num;

    // Input matrix
    printf("Rows number: ");
    scanf("%d", &rows);
    printf("Cols number: ");
    scanf("%d", &cols);

    // Alloc matrix
    matrix = malloc(rows*cols);  
    max = malloc(rows);  
    min = malloc(rows);  

    // Fill matrix
    for (int i=0; i<rows; i++)
        for (int j=0; j<cols; j++){
            printf("[%d, %d] = ", i, j);
            scanf("%d", matrix+(i*cols)+j);  // Store at offset
        }

    diag = 0;
    for (int i=0; i<rows; i++){
        max[i] = matrix[i*cols];  // Assume 1st is max
        min[i] = matrix[i*cols];  // Assume 1st is min
        for (int j=0; j<cols; j++){
            num = *(matrix+(i*cols)+j);  // Store num of the matrix temporaly for fast access
            if (i == j) diag += num;  // If in main diagonal, add to diag sum
            if (num > max[i]) max[i] = num;
            else if (num < min[i]) min[i] = num;
        }
    }

    printf("\nDEBUG for [2,2] value %d\n\n", matrix[8]);

    for (int i=0; i<rows; i++){    
        for (int j=0; j<cols; j++){
            printf("%d ", *(matrix+(i*cols)+j));
        }
        printf("| max=%d, min=%d", max[i], min[i]);
        printf("\n");
    }

    printf("\nDiagonal sum = %d", diag);


    return 0;
}

Screenshoot with 3x3 input enter image description here

Screenshoot with 4x4 input enter image description here

Issue

When I type the elements for a 3x3 matrix with the elements from 1 to 9 as the matrix values, the last element bugs and shows the value 3 instead of 9.

I've tried with other inputs and the bug seems to be copying the value from the 1st row, 3rd col.

This drives me crazy because when I run it with the debugger, the program works as expected.

Workaround solutions

The probles solves if I define the matrix as an array (int matrix[i][j]) or the max and min arrays, but that is not the solution I want.

Also if I allocate the matrix with some extra space, the problem is gone. Again, an unwanted solution.

Hypothesis

I think that, apart from me messing something up, the second call to malloc (max = malloc(rows)) is allocating the array overwritting the previous malloc call, the one that allocated the matrix in the previous line.

Note

Thank everyone for helping, contact me for extra information about the issue


Solution

  • The workarounds are on the right track in terms of understanding the underlying issue, it's about space. You need to malloc enough bytes to store the ints.

    How many bytes? If a single int occupied one byte of memory then the answer would be rows * cols (which is where you are now). But that's not the case, an int actually occupies either two bytes or four bytes (usually four, but it depends on the compiler). Use sizeof to determine the size of an int and factor this into the calculation.

    Thus:

        matrix = malloc(sizeof(int) * rows * cols);  
        max = malloc(sizeof(int) * rows);  
        min = malloc(sizeof(int) * rows);