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

int main()
{
    int a[3][3]={{0,1},{2,3},{5,6}},**b,i,j;
    b=(int **)calloc(3,sizeof(int *));
    for(i=0;i<3;i++)
    {
        b[i]=(int *)calloc(3,sizeof(int));
    }
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            b[i][j]=(i+1)*(j+1);
        }
    }

    printf("%d %d %d %d\n",*(*a+4),**a+4,*(*b+4),**b+4); 
    printf("%d %d %d %d\n",*(a[2]-2),**(a+2),*(b[2]-2),**(b+2)); 

    return 0;
}

Output I am getting :

3 4 2 5
3 5 6 3

According to me I should be getting:

3 4 4 5
3 5 4 3

Reason:

*(*b+4) = *(b[0]+4). b[0]+4 points to b[1][1] so this value should be 4, which is the value of matrix at 1,1 position

*(b[2]-2), Now b[2]-2 points to b[1][1], so value again should be 4

please tell me why am getting different output

6
  • 1
    Why do you think b[0]+4 points to b[1][1]? You allocated each row separately, they're not contiguous. Commented Oct 30, 2019 at 22:01
  • All the rows of a are contiguous because it's a 2-dimensional array. Commented Oct 30, 2019 at 22:02
  • Try printing the values of b[0] and b[1] to see that they differ by more than 3. Commented Oct 30, 2019 at 22:06
  • @Barmar I read calloc allocates contiguous memory? Commented Oct 30, 2019 at 22:15
  • 1
    Each call to calloc() allocates contiguous memory, but it's not contiguous with other calls. Commented Oct 30, 2019 at 22:18

1 Answer 1

1

When you declare a 2-dimensional array like a[3][3], the entire array is contiguous, so a[0][2] is immediately followed by a[1][0]. When you use pointer arithmetic on a, you can depend on this ability to cross rows, as long as you stay within the entire a array.

But when you use an array of pointers, there's no reason to expect each row to be contiguous with the previous row. The memory allocated by each call to malloc() is unrelated to previous calls. Also, malloc() has to ensure that the memory is properly aligned for any datatype; if the size you're allocating is not a multiple of this, they can't possibly be contiguous. And many dynamic memory allocators store bookkeeping information (such as the size of the allocation, so that free() knows how much memory to reclaim) before the allocation, so that also prevents allocations from being contiguous.

It's undefined behavior to access the memory outside the allocation size. Since b[0] points to an allocation of 3 int, b[0]+4 is outside this allocation, and *(b[0]+4) causes undefined behavior.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.