0

I'm working on a C program that involves generating adjacency matrices of random graphs. Here is a snippet of the source code:

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

#include "test.h"

int main()
{
    int **A = create_matrix(4, 3);
    destory_matrix(A);
    return 0;
}

int** create_matrix(int size, int seed)
{
    // Allocate space for matrix
    int **A = malloc(size * size * sizeof(int));

    for (int r = 0; r < size; r++) {
        A[r] = malloc(size * sizeof(int));
    }

    // Fill entries
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            A[i][j] = seed * (i + 1) * (j + 1);
        }
    }

    return A;
}

void destory_matrix(int **A)
{
    int size = sizeof(A[0]) / sizeof(int);

    for (int r = 0; r < size; r++) {
        free(A[r])
    }

    free(A);
}

This portion of the code is responsible for creating the matrix (the create_matrix() function) and free'ing memory (destroy_matrix()). I'm looking at destroy_matrix(), and noticed that when a 4x4 matrix is passed in, the variable size evaluated to 2, rather than 4. Could anyone explain why this happens?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Ryan
  • 7,621
  • 5
  • 18
  • 31

2 Answers2

1

I think you have a basic misunderstanding of the sizeof operator. It can't, in general, be used to get the size of dynamically allocated compound objects. The sizeof operator returns to you the size based on the type of the operand. In your case, the type of the operand is int *. I guess you are running on a 64 bit system. So the sizeof any pointer is 8. Hence your size variable will always be 2 no matter the size of your matrix.

kaylum
  • 13,833
  • 2
  • 22
  • 31
1

The sizeof operator applied to a pointer returns the size of the pointer type, not the size of any allocated memory it happens to point to.

This is one of the key differences between an array type and a pointer type in C (note: arrays can decay to pointers). sizeof applied to an statically specified array type (e.g. int foo[n];) will get you the size of the array in bytes.

Since your word size is probably 8 bytes (64-bit), the size of a pointer will be 8 bytes, and if sizeof(int) is 4 bytes (32-bits), you have 8 / 4 = 2;

You need to consider some other way to store the dimensions of your matrices if you need runtime-sized heap-allocated matrices, e.g. a struct that stores the dimensions and a pointer to the allocated memory. It would be better to avoid possible heap-fragmentation altogether, though.

Try this if you have C99:

int n = 4, m = 5;
int (*A)[n] = malloc(m * sizeof A[0]));
free(A);

This allocates an m length array of int[n] as a single block, so you can do size_t n = sizeof(A)/sizeof(A[0]); to get one dimension(n) but you'll need to store m if you want to iterate correctly.

Iskar Jarak
  • 5,136
  • 4
  • 38
  • 60