0

Why is this correct

int *block = malloc(2*sizeof(int)); 
size_t block_size = sizeof(block) / sizeof(block[0]);  //block_size = 2; correct

But this fails?

int **block = malloc(2*sizeof(int)); 
size_t block_size = sizeof(block) / sizeof(block[0]); // block_size = 1; incorrect

By the way, I thought I couldn't use sizeof accurately on pointer variables? How come it works for the first one?

Community
  • 1
  • 1
George Newton
  • 3,153
  • 7
  • 34
  • 49
  • You can use sizeof accurately. It accurately returns the size of a pointer. The trick you are trying to use only works for arrays. And note that it's just that - a trick that only works for arrays. It's not a magic way to see the size of what something is pointing to. – user253751 Mar 18 '14 at 04:59

3 Answers3

4

The first one only works by accident. Change that 2 to a 3 and watch what happens.

size_t block_size = sizeof(block) / sizeof(block[0]);  //block_size = 2

Since block is an int * and block[0] is an int, this gives the ratio of the size of a pointer to an integer to the size of an integer. This happens to be two on your platform. I'd guess your integers are 32-bits and your pointers are 64-bits.

size_t block_size = sizeof(block) / sizeof(block[0]); // block_size = 1

Since block is now an int**, this gives the ratio of the size of a pointer to a pointer to an integer to the size of a pointer to an integer. Likely on your platform all pointers are the same size.

If you want to know the size of a block you allocated, you have to keep track of it. The sizeof operator doesn't do what you think it does -- it tells you the sizes of types, not blocks of memory.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • `all pointers are the same size.` - Not true. The standard does not guarantee that pointers to different types are the same size. – Ed S. Mar 18 '14 at 03:53
  • Before your edit you said "all pointers are the same size." That's a guarantee if I've ever heard one. I'm not saying that you're often wrong in practice, just a nitpick. I upvoted the answer. – Ed S. Mar 18 '14 at 03:54
1

No, that's not right. None of it should work, and none is actually working here.

sizeof(block) != sizeof(block[0])+ sizeof(block[1])

So, to assume

block_size = sizeof(block) / sizeof(block[0]); = 2

is wrong!

int*/void*/char* are all just variables to hold addresses, they all 'mostly' are of same size.

And a pointer points to a block of memory which could be any no of bytes, doesn't depend upon the size of the pointer.

brokenfoot
  • 11,083
  • 10
  • 59
  • 80
0

Assuming your pointers are 8 bytes size and int is 4 bytes: lets look at :

int *block = malloc(2*sizeof(int)); 
size_t block_size = sizeof(block) / sizeof(block[0]); 
  1. block has been allocated 2*4 = 8 bytes of memory
  2. sizeof(block) should return 8 because it is size of pointer (this will be same for int*, char*,void* etc)
  3. sizeof(block[0]) which is size of first element pointed by block should return 4 so you have 8/4 = 2

next lets see :

int **block = malloc(2*sizeof(int)); 
size_t block_size = sizeof(block) / sizeof(block[0]); // block_size = 1; incorrect
  1. block is pointer to pointer to int(double pointer)
  2. block will be holding address(i.e., pointer to int), so sizeof(block) should return 8 and sizeof(block[0]) which is again holding address should return 8. Note that: *block[0] is element and block[0] is address
  3. so sizeof(block)/size[0] is 8/8 = 1

Hope this will help you

AravindMS
  • 49
  • 7