Memory is organized in a program in different areas:
1. The initial data area of the program. Here are stored compile time constants like the character strings we use, the tables we input as immediate program data, the space we allocate in fixed size arrays, and other items. This area is further divided into initialized data, and uninitialized data, that the program loader sets to zero before the program starts. When you write a declaration like int data = 78; the data variable will be stored in the initialized data area. When you just write int data; the variable will be stored in the uninitialized data area.
2. The stack. Here is stored the procedure frame, i.e. the arguments and local variables of each function. This storage is dynamic: it grows and shrinks when procedures are called and they return. At any moment we have a stack pointer, stored in a machine register, that contains the machine address of the topmost position of the stack.
3. The heap. Here is the space that we obtain with malloc or equivalent routines. This also a dynamic data area, it grows when we allocate memory using malloc, and shrinks when we release the allocated memory with the free() library function.