Reputation: 237
Trying to understand the usage and memory allocation of double pointers in C.
Below is my code: -
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
printf("Enter rows and columns respectively: -\n");
int rows, columns;
scanf("%d%d", &rows, &columns);
int **matrix;
matrix = calloc(rows, sizeof(int));
int i, j;
for(i = 0; i < rows; i++)
{
matrix[i] = calloc(columns, sizeof(int));
}
printf("Enter your elements\n");
for(i = 0; i < rows; i++)
{
for(j = 0; j < columns; j++)
{
scanf("%d", &matrix[i][j]);
}
}
printf("Your elements are: -\n");
for(i = 0; i < rows; i++)
{
for(j = 0; j < columns; j++)
{
printf("%d ", matrix[i][j]);
}
printf("\n");
}
free(matrix);
return 0;
}
After getting Segmentation fault: 11
, I searched on the net and found out that instead of writing this: -
int **matrix;
matrix = calloc(rows, sizeof(int));
I should write: -
int **matrix;
matrix = calloc(rows, sizeof(int*));
After making the above changes, my code works fine.
My question is: -
- What is the difference between sizeof(int) and sizeof(int *)?
- Don't both of them allocate 4 bytes? (int occupies 4 bytes and int* (which is noting but a pointer) also occupies 4 bytes?
- If both of them allocates the same space, then why was I getting a Segmentation fault in the first case?
Upvotes: 0
Views: 238
Reputation: 545588
Don't both of them allocate 4 bytes? (int occupies 4 bytes and int* (which is noting but a pointer) also occupies 4 bytes?
What makes you think that a pointer is four bytes? On most modern (64 bit) architectures, pointers to object are 8 bytes, not 4.
Hence, in general sizeof(int) ≠ sizeof(int *)
. But you can’t make many assumptions about the sizes of objects in portable C code, and you definitely can’t assume that sizeof(int) == 4
, or sizeof(int*) == 8
(nor 4
). Depending on the platform, these sizes vary. They could also have the same size. You just can’t assume that.
To avoid confusion between pointer and pointee size, some people (me included) recommend using the object name in the sizeof
expression in allocations, rather than the type name:
int **matrix = calloc(rows, sizeof *matrix);
// …
matrix[i] = calloc(columns, sizeof **matrix);
This makes it clear what you are trying to allocate. Note that sizeof expr
does not evaluate expr
; this is important, since the expressions *matrix
and **matrix
are invalid before you’ve allocated the memory — deferencing the unassigned pointer would be undefined behaviour. But sizeof
only determines the object size of the expression without actually evaluating it.
Upvotes: 2