0

My friend and I are arguing over this one.

char **array[2][2]; 

Is the size that this takes up in memory 8 + 2*2*8 — 8 for the pointer to the array of pointers and then 32 for the array of pointers? Or is it just 8 because we are declaring a pointer to an array of pointers. This declarations doesn't have to allocate space for the array of pointers, just the pointer?

  • 1
    You have an array of 4 pointers; it occupies `4 * sizeof(char **)`, which will be 16 or 32 bytes depending on whether it is a 32-but or 64-bit compilation. – Jonathan Leffler Jun 05 '18 at 22:59
  • @JonathanLeffler Why are u grouping the double pointers together? Why is it not a pointer to an array of pointers? –  Jun 05 '18 at 23:00
  • 3
    Because it is a 2D array of `char **`, @bananateam. Each element of the array is a `char **`. There is no extra storage required. – Jonathan Leffler Jun 05 '18 at 23:02
  • A pointer to an array of pointers would be written as `char *(*ptr_to_array_of_ptrs)[2];` if the target is a 1D array of pointers. – Jonathan Leffler Jun 05 '18 at 23:09
  • 3
    You could ask the compiler: `printf("%zu", sizeof(array))`. The compiler is never wrong ;) – user3386109 Jun 05 '18 at 23:14
  • @user3386109 unless they are using a MS compiler that does not support `%zu` :D – M.M Jun 05 '18 at 23:14
  • @JonathanLeffler Thank you I didn't know there was a difference! –  Jun 05 '18 at 23:16
  • @M.M I tried using sizeof on Xcode but it was giving me large negative numbers when I used "%d" and "%lu" as recommended by Xcode. –  Jun 05 '18 at 23:17
  • See [Correct format specifier to print pointer address?](https://stackoverflow.com/a/9053835/15168) – Jonathan Leffler Jun 05 '18 at 23:20
  • @PeteBecker It seems like youre saying it’s just a pointer, and it can point to anything, so it should be just 8 bytes but apparently this is an array of char**, and is 32 bytes because theres 4. –  Jun 05 '18 at 23:56
  • @bananateam, the right operators have precedence over the left ones, so it's a two dimensional array with two positions in either direction. The double pointer has nothing special over the single pointer, as they are represented by an address (well, one is an address of an address, while the other is an address to a char) so there are `2x2 = 4` pointers in the array. @jonathanLeffler is right in his calculations, and no grouping is done. – Luis Colorado Jun 06 '18 at 11:45
  • @M.M, in case your compiler doesn't use `%zu` format (that's not a compiler problem, but rather a `printf()` implementation, so it's not VC specific. But then, you can use `%llu` and convert the pointer with a cast, as in `(unsigned long long) sizeof(array)` before passing it to printf. (same for `%lu` and `(unsigned long) sizeof(array)` if your platform doesn't support 64bit addresses) – Luis Colorado Jun 06 '18 at 11:50
  • You are asking a question related to `printf(3)` format implementation, which is not a C++ function and tag the question as **C++**. Remove the C++ tag as this question has nothing to do with the implementation of the `printf(3)` function, so it is not a C++ question. – Luis Colorado Jun 06 '18 at 11:54

2 Answers2

9

As cdecl could have told you (with a little fiddling), your declaration

char ** array[2][2];

declares array as an array of two arrays of two pointers to pointers to char. That means a total of four elements of type char ** (and nothing else). C does not specify how large pointers are, nor even that pointers to different types have the same size, but it is common on 64-bit implementations for all pointers to be 8 bytes wide. On such an implementation, the size of the declared object is 2 * 2 * 8 == 32 bytes. There is no extra pointer.

If you wanted a pointer to a 2 x 2 array of char *, that would be different:

char * (*array)[2][2];

... and the size of that is indeed the size of one pointer. No storage is reserved in that case for the pointed-to 2D array.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • Okay this makes more sense. I thought it was creating the 2nd case you mention and didnt know there was a distinguishment like that between the 2. THANKS! –  Jun 05 '18 at 23:15
2

The compiler allocates your whole array (32 bytes). You can investigate these questions with sizeof():

#include <stdio.h>
char ** array[2][2];
int main() {
    printf("size = %zu\n", sizeof(array));
    printf("size[0] = %zu\n", sizeof(array[0]));
    printf("size[0][0] = %zu\n", sizeof(array[0][0]));
    return 0;
}

On x86_64 architecture returns:

size = 32
size[0] = 16
size[0][0] = 8

Each pointer is 8 bytes long, and your two-dimensional array contains 4 total.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
srking
  • 4,512
  • 1
  • 30
  • 46
  • hmm i think i did sizeof the same and used %d but got a huge negative number, dont know what i did –  Jun 05 '18 at 23:24
  • 1
    @bananateam: Using `%d` to print either pointers or `size_t` values (the result of `sizeof()`) is basically wrong. Use `%p` for pointers (converting to `void *`) and use `%zu` for `size_t`. – Jonathan Leffler Jun 05 '18 at 23:27