edited by
1,316 views

2 Answers

Best answer
4 votes
4 votes

With this line,

int **arr=(int**) malloc(r* sizeof(int*));

you are telling to create an array of pointers to integers. It would return pointer to pointer-to-integer (array). It would contain 'r' locations which where you would (subsequently) store pointer to integer.

After this call, the memory which is allocated would look like below

With this, 

for(i=0; i<r; i++)
   arr[i]=(int*) malloc(c* sizeof(int));

You are reserving space to store integers. Space is being allocated for each pointer (created in above figure) which would reserve space for storing 'c' integers.

After this call, the memory which is allocated would look like below

selected by
2 votes
2 votes

code :

#include <stdio.h>
#include <stdlib.h>
#define NUM_ROWS 3
#define NUM_COLS 2
int main() {

	int **arr = (int **)malloc(NUM_ROWS * sizeof(int*));

	printf("address of arr = %p\n",&arr);
	printf("value inside arr = %p\n",arr);


	for(int i=0;i<NUM_ROWS;i++) {
		printf("arr + %d = %p\n",i,arr + i);
	}
	

	for(int i=0;i<NUM_ROWS;i++) {

		arr[i] = (int *)malloc(NUM_COLS * sizeof(int));
		printf("*(arr + %d) is initialized with = %p \n",i,arr[i]);	
	}


	// access one element :

	arr[2][1] = 4;

	printf("arr[2][1] = %d\n", *(*(arr+2) + 1) );

	for(int i = 0;i<NUM_ROWS;i++) {
		free(arr[i]);
	}
	free(arr);
	return 0;
}

Explanation :


Assume that:

  • the size of any pointer = 4 Bytes
  • sizeof(int)     = 4 Bytes

Therefore,

  • malloc(NUM_ROWS * sizeof(*int)) is basically malloc(12)

So, malloc will return a void* pointing to the first byte of the contiguous area of $12$ Bytes.

Assume that first Byte address is $2000$

int **arr = malloc(NUM_ROWS * sizeof(*int));

arr is another pointer variable (just ignore ** for a moment)

we will assign value $2000$ to arr



Since arr is a pointer we can do pointer arithmetic on arr.

We also know that,

arr + offset = arr + offset * sizeof(*arr);

arr is a double pointer. So if we dereference it one time (*arr) it will again be a pointer (although single).
So, sizeof(*arr) = 4 according to our assumption.

Therefore,

arr+0 = 2000
arr+1 = 2004
arr+2 = 2008


Now,

Let's look at *(arr+i) for i = 1

  • arr is a double pointer
  • arr + 1 is also a double pointer
  • *(arr+1) is a single pointer with size of $4$ Bytes.

We are reading a memory location of $4$ Bytes as shown below.


Currently, this location is uninitialized. 
So we will again call malloc(NUM_COLS*sizeof(int)) or malloc(8) which will allocate $8$ Bytes of a memory block and returns the address the of the first Byte. We will take that address and assign it to *(arr+1), as shown below.


Likewise, we will initialize all *(arr+i) or arr[i] for i = 0,1,2

Finally, this is the memory layout. 



Output in an actual system :

address of arr = 0023FF10
value inside arr = 004915B0
arr + 0 = 004915B0
arr + 1 = 004915B4
arr + 2 = 004915B8
*(arr + 0) is initialized with = 00491590 
*(arr + 1) is initialized with = 004915C8 
*(arr + 2) is initialized with = 004915D8 
arr[2][1] = 4

NOTE :

casting malloc is not required in c : But we should use it for portability issue.

Related questions

0 votes
0 votes
1 answer
2
Lakshman Bhaiya asked Oct 22, 2018
3,133 views
A is a 2D-array with the range [-5....5,3......13] of elements.The starting location is 100. each element accupies 2 memeory cells.Calculate the location of A[0][8] using...
2 votes
2 votes
1 answer
4
Beyonder asked Dec 20, 2017
2,026 views
Consider a lower triangular Matrix A[-25....+25, -25....+25], base address (BA)=0, size of element = 100 Byte. Find the location of a [-20][-21] (Ordering: Row Major)?