if we wanted to allocate dynamically an array of 4 pointers to characters using malloc we write for example : char **arr = malloc(4 * sizeof(char *));
. i know that malloc returns the address of an allocated memory (in our case if the size of the pointer is 8 bytes it will return the address of the allocated 32 bytes) and arr is a pointer to pointer so How is it considered that the those 32 bytes are pointers and not another data So that we can assign the address of the first pointer to arr?
CodePudding user response:
To assign values to the allocated memory you will use the pointer arr
that has the type char **
due to the declaration
char **arr = malloc(4 * sizeof(char *));
The function malloc
returns a pointer of the type void *
that can be assigned to any other pointer to object.
For example you could write
int *arr = malloc(4 * sizeof(char *));
The function argument expression specifies only the size of the allocated memory.
So it depends entirely on you how you will use the allocated memory.
CodePudding user response:
How is it considered that the those 32 bytes are pointers and not another data So that we can assign the address of the first pointer to arr?
You tell the compiler what type to treat the memory as by the way you write expressions.
After you declare char **arr
, the type of arr
is char **
, so the type of arr[i]
is char *
. Then, if you write arr[i] = …
, the left operand of =
, arr[i]
, is used to know what type is being assigned. The value of the right operand of =
will be converted to this type and stored into the memory of arr[i]
.
If, after this, you wrote int *p = (int *) arr;
and then p[i] = 3;
, then the type of p[i]
would be int
, and the value 3 would be stored in the memory using the int
type.
Also, the return type of malloc
is void *
, which is a pointer to an incomplete type. The rules of C allow automatically converting this to a pointer to any object type. So, in char **arr = malloc(…);
, the return value of malloc
is automatically converted to the type of arr
, and the new pointer points to the same address, just with a different type.
Originally C was very flexible about this; you could write memory as one type and read it as another. Like assignments, expressions that used a value from memory instead of storing it to memory would use the type of the expression to know how to interpret the memory. However, to support program optimization, the C standard has added rules. There are now limits on how you can access memory if you want the behavior to be defined by the C standard.
For dynamically allocated memory, as with malloc
, you can write any type of data to that memory, and then you can read back that same type of data. You can also write a new type and then read back that same new type. However, if you want to read back a different type than the type used to write, there are restrictions:
- You can read the data using a compatible type.
- You can also read the data using additional qualifiers (notably
const
andvolatile
). - You can read signed integer types as their unsigned counterparts and vice-versa.
- You can read as an array, structure, or union that has one of the above among its members.
- You can read using a character type.