Given the declaration
int a[5];
you get something like this in memory (each square represents an int
object):
+---+
a: | | a[0]
+---+
| | a[1]
+---+
| | a[2]
+---+
| | a[3]
+---+
| | a[4]
+---+
That's it - no other metadata regarding size or type or starting address is stored as part of the array. All you get is a contiguous sequence of objects of the specified type. There is no object a
that's separate from the array elements themselves.
what will happen if I declare an int8_t arr[2]
, will it go wrong?
Not sure what you mean. Declarations are not processed at runtime; during translation, the compiler analyzes the code and generates the machine code necessary to set aside any storage at program or function entry.
does compiler have a list of the allocated memory and check when it declares variable?
During translation, the compiler will keep track of declarations (using what's often called a symbol table) and will issue any diagnostics if the declaration isn't valid (incomplete type, no size, syntax error, whatever). No such checks are done at runtime.
calling malloc(1)
in a while loop, why their return value has the difference of 0x20?
Because unless you're also calling free()
on the memory you allocated, you're allocating a new block of memory every time through the loop, each of which starts at a different address.
Depending on the implementation, malloc
may allocate more memory than necessary for the given object to store bookkeeping information about that object. After all, when you call free
, all you give it is the starting address of the memory you allocated - you don't tell it how much memory to free. That information has to be stored somewhere, and many implementations set aside some extra space prior to the allocated block to do so:
+---+ ---+
| | |
+---+ |
... +---- bookkeeping data
+---+ |
| | |
+---+ ---+
| | | <--- this byte's address returned by malloc
+---+ |
| | |
+---+ +---- Requested block
... |
+---+ |
| | |
+---+ ---+