Search code examples
cmalloc2dinternal

C programming 2D array malloc: Interesting values after every row. Seek explanation


I referred this, this and this SO posts before asking this question:

While teaching dynamic memory allocation to a friend, I wrote a simple program, whose snippet is below:

matrix = (int**) malloc (sizeof(int*) * m);
for (i = 0; i < m; ++i)
matrix[i] = (int*) malloc (sizeof(int) * n);

for (i = 0; i < m; ++i)
  for (j = 0; j < n; ++j)
      matrix[i][j] = rand() % 100; /*some random value*/


for (i = 0; i < m; ++i)
{
  for (j = 0; j < n; ++j)
  {
      printf("(%8u)%-5d", &matrix[i][j], matrix[i][j]);
  }

  /* Print element just after the first row*/
  printf("(%8u)%-5d", matrix[i] + n, *(matrix[i] + n));

  /* Print second NEXT element just after the first row*/
  printf("(%8u)%-5d", matrix[i] + n + 1, *(matrix[i] + n + 1));
}

When I run this program as

unmesh@unmesh-laptop:~/teaching/C/Day3$ ./matrix
Enter number of rows: 3
Enter number of columns: 3

(141189144)1    (141189148)2    (141189152)3    **(141189156)17**   (141189160)2    

(141189160)2    (141189164)3    (141189168)4    **(141189172)17**   (141189176)3    

(141189176)3    (141189180)4    (141189184)5    (141189188)135105(141189192)0 

I am curious about the value 17. If I am not mistaking, there are three calls to malloc in this invocation, So memory may not be contiguous as can be observed. But I run the program with m=n=4 or m=n=5, then I can see the value 25 after each row. For m=n=6 and m=n=7, value 33 is observed.

More interesting is the fact that when n is odd (n=3 / n=5 ..) this value is stored immediately after the row ends. example row when m=n=3

Values  1        2       3       17  
Address 100      104    108     112  

Next row starts from 116

When n is even, it is stored after 4 bytes example row when m=n=2

Values  1        2       0       17  
Address 100      104    108     112  

Next row starts from 116

Question is where do these values 17/25/33 come from ? Why are they always the same ? I hope they are not garbage and must have some meaning .. I fail to deduce. Please help.


Solution

  • You're seeing the internal bookkeeping information malloc stores to keep track of blocks that have been allocated. The precise nature and size of this information varies from system to system, but it is often the case that malloc rounds up the size requested so that, when combined with its bookkeeping info, the resulting block is a multiple of the largest alignment generally required for your machine. In your case, it looks like the alignment is 8 bytes (two ints), leading to the even/odd behavior you see. The 17/25/33 values you see are likely the sizes of the allocated blocks (including the padding and size info) with the lowest bit set to indicate an in-use block.