sizeof has a feature that it will know the type of an expression. So, if p is an int, then sizeof p will produce the number of bytes in an int. (Note that sizeof is an operator, not a function, so you do not need parentheses for its operand here.)
If p is a pointer to an int, then the type of *p is int. Then sizeof *p is the size of an int. You can use this whenever you allocate memory for a single object and assign it to a pointer to that type of object:
p = malloc(sizeof *p);
You can also use it when declaring and initializing a pointer:
int *p = malloc(sizeof *p);
(Even though p is not initialized when the value of malloc(sizeof *p) is evaluated, this works because the value of p is not used in the expression. Only its type is used.)
To allocate space for multiple objects of the same type, simply multiply the size:
int *p = malloc(3 * sizeof *p);
This works for any type of object, including pointers to pointers. This code allocates space for 3 pointers to int:
int **p = malloc(3 * sizeof *p);
The above saves you the trouble of figuring out the syntax for types. However, if you wish to do it yourself, there are two rules:
- The pointer to an object type has one more pointer level than the object type. When assigning to an
int *, the size of an int should be used. When assigning to an int **, the size of an int * should be used.
- When using types in expressions, you do need parentheses around them. This is not because
sizeof is a function but because the grammar needs help distinguishing types:
int **p = malloc(3 * sizeof (int *));
Hello **hello_array; declares hello_array to be a pointer to a pointer to hello_array. This can act as a two-dimensional matrix of Hello objects, not a one-dimensional array of Hello objects.
Since hello_array points to pointers to Hello, you need to allocate space for pointers:
hello_array = malloc(n * sizeof (Hello *));
hello_array = malloc(n * sizeof *hello_array); // Same result.
When allocating memory for the Hello objects, which you will point to with *hello_array or hello_array[i], you need to allocate space for Hello objects:
hello_array[i] = malloc(m * sizeof (Hello));
hello_array[i] = malloc(m * sizeof *hello_array[i]);
// Simple rule: Always use `sizeof *x`, where `x` is the pointer being assigned to.
Hello **hello_arrayis supposed to point to an array of pointers. I.e. each element is aHello*and thereforesizeof(Hello*)is correct. BTW - why do you multiply by 1 ? if you want only 1 element simply keep thesizeof(or don't use an array at all..).sizeof(Hello*)can be used for allocating the array, then issizeof(Hello*)=sizeof(void *)? As they are both are pointers, the pointer*type length should be the same for any types in c language. Can I simply usehello_array = malloc(sizeof(void*) * 1);?hello_array = malloc(sizeof(void*) * 1);?" Only if the pointers really are the same size, which is true on most architectures, but should not be assumed for portability. On some architectures, function pointers are not the same size as object pointers, for example.sizeof(Hello*)=sizeof(void *)", This probably happens to be the case in the environment you are using, but it's not guaranteed. Pointers of different type do not have to be the same size, and have not always been the same size historically.void*will be at least as large as any non-function pointer, but it could be larger thanHello*.void *" --> note thatvoid *is a pointer, not an array nor an array type. Array are not pointers. Pointers are not arrays.