What does LIFO really mean? - c++

As mentioned in this tutorial:
http://www.learncpp.com/cpp-tutorial/79-the-stack-and-the-heap/
In computer programming, a stack is a container that holds other
variables (much like an array). However, whereas an array lets you
access and modify elements in any order you wish, a stack is more
limited. The operations that can be performed on a stack are identical
to the ones above:
1) Look at the top item on the stack (usually done via a function
called top()) 2) Take the top item off of the stack (done via a
function called pop()) 3) Put a new item on top of the stack (done via
a function called push())
But if I defined two variables in C++ I do not have to use them in the same order of definition:
Example:
int main() {
int a;
int b;
b = 5;
a = 6;
}
Is there a problem on this code? I can use them in any order I like!! I do not have to use the a first then the b.
Am I misunderstanding something? What is it?

You are confusing two different kinds of stacks.
One stack, is where some of the memory for your application is allocated. This would be part of a discussion about the stack and heap and where your memory is allocated.
The other kind of stack is a data structure that conforms to a LIFO style of access. This could be implemented using a std::vector or other forms of data structures.

Yep, the "automatic storage" that holds a called method's local variables is allocated in a stack. But with the automatic storage stack you push and pop (variable sized) "stack frames" that contain all of the local variables for a method, not individual values.
This is conceptually similar to the kind of stack discussed in the article you quote, except that the items being pushed and popped are much larger.
In both cases the mechanism is "LIFO", since when you call a method you essentially return by "popping the stack" -- you always have to return from methods in the opposite order that you called them.

Am I misunderstanding something? What is it?
The "stack" that you're putting 'a' and 'b' on is (WARNING HUGE SIMPLIFICATIONS AND CONCEPTUALIZATIONS AHEAD) not made out of variables; it is made out of stack frames. A stack frame consists of the parameters to a function and a space for its return value, and sometimes also the variables used within the function (except that these can also be held in registers, and sometimes parameters are also passed via the registers). "Pushing" onto this stack is accomplished by calling a function. "Popping" from this stack is accomplished by returning from a function. You indeed only have access to the "top" element; you can't just read the variables of the function that called the current function, unless they were explicitly passed in as parameters.

Like any other data structure , stack is a data structure which follows LIFO(last in first out) principle.As mentioned in your question it does push and pop operation for inputting and retrieving data according to LIFO principle.
Every process consists of basically 4 portions of address space that are
accessible to the process
when it is running
Text - This portion contains the actual m/c instructions to be
executed. On many Operating Systems this is set to read only, so that the
process can't modify its instructions. This allows multiple instances of
the program to share the single copy of the text.
Data - This portion contains the program's data part. It furthere
divided into
1) Initialized Read Only Data - This contains the data elements
that are initialized by the program and they are read only during the
execution of the process.
2) Initialized Read Write Data - This contains the data elements
that are initialized by the program and will be modified in the course of
process execution.
3)Uninitalized Data - This contains the elements are not
initialized by the program and are set 0 before the processes executes.
These can also be modified and referred as BSS(Block Started Symbol). The
adv of such elements are, system doesn't have to allocate space in the
program file for this area, b'coz it is initialized to 0 by OS before the
process begins to execute.
Stack - This portion is used for local variables, stack frames
Heap - This portion contains the dynamically allocated memory
int abc = 1; ----> Initialized Read-Write Data
char *str; ----> BSS
const int i = 10; -----> Initialized Read-Only Data
main()
{
int ii,a=1,b=2,c; -----> Local Variables on
Stack
char *ptr;
ptr = malloc(4); ------> Allocated Memory in Heap
c= a+b; ------> Text
}
Data, store data
Text, store code
There are 3 (main?) segments/sections of the file produced by a linker.
text - program text (and apparently const char arrays. maybe other 'const' arrays, since those can not be changed anyway). I am not 100% sure about the array part, maybe
someone will correct me.
data - initialized global data. see examples below.
bss - uninitialized global data.
Here are some examples
int x = 1; /* goes into data */
int y; /* goes into bss */
const int z = 1;
this, we've seen go into 'text', since can't be changed anyway,but can be protected
const char array[] = {'a','b'....etc}
/* the rest goes into text */
int main(void)
{
return EXIT_SUCCESS;
}
Block Started by Symbol
(BSS) The uninitialised data segment produced by Unix linkers. The other segments are the "text" segment which contains the program code and the "data" segment contains
initialised data. Objects in the bss segment have only a name and a size but no value.

You don't have to use them in the order defined. But they are destroyed - taken off the stack- in that order. LIFO does not refer to access, only putting things on or taking them off the stack.
You can trivially observe this by changing int for a type which prints in it's destructor.

A stack is a standard data structure that's used all over the place. A thread's so called stack is in fact an implementation of this paradigm. There's a stack pointer (usually in a processor register) that points to a memory location. Data is 'pushed' onto this stack by moving the sp. We 'pop' by returning the value it points to and moving the sp the opposite direction.
As far as your a, b declared above it makes no difference. They're both allocated before they get used.

Stack program:
Your example program is not an implementation of stack. Stack shall store elements like an array (or by some means) where elements can be pushed (stored) or poped (pulled out) in LIFO (last in first out) order. It's implementation is not as simple as declaring two variables. Standard C++ provides stack class so that you can use it without having to implement on your own.
Stack Memory:
Variables in a function are stored in stack memory (Somewhere in the RAM) in LIFO order. From your example, Variable a will be created and pushed to stack memory. Then, the variable b is pushed to stack memory. After the function completes it's execution, the variables are destroyed in LIFO fashion. So variable b is the first to get destroyed and finally variable a gets destroyed. You don't write the code for it. The compiler takes care to write assembly low level code for it.

Related

what's the difference between callstack and stack?

I think I might be asking a very wrong question, but I really tried to understand it by googling, but with no luck.
As we know, we have a stack and heap. Heap for the dynamically allocated ones, stack for local variables and e.t.c.
Let's say I have the following c++ code.
void bla(int v1, int v2, int v3) {
int g = v1 + v2+ v3;
}
void nice(int g){
int z = 20;
int k = 30;
bla(g, z, k);
}
int main(){
cout<<"Hello World";
nice(40);
}
Now, let's imagine there's a stack. I understand that for example values z,k,g will be stored on stack. But when I call the function nice which calls bla where are those stored ? I've read that each function execution causes call stack size to increase by 1. I'd say that even creating local variables also causes call stack to be increased by 1.
So, how are those(callstack, stack) related at all ?
Here is my assumption:
When we call nice, completely new stack gets created. In there, we store z and k. When nice calls bla , now another stack gets created for bla and this second stack stores v1,v2,v3,g. and so on. each function needs its own callstack,but we can call this stack too.
Each running process is allocated a chunk of memory which it calls "the stack." And, this area of memory is used both to represent the "call/return sequence" (through what are known as "stack frames"), and the so-called "local variables" that are used by each routine that is called. They are one and the same.
Usually, different CPU registers are used to point simultaneously to each thing. One register points to the "local variable" values, while an entirely different register points to the "stack frame." (In interpreters, a similar mechanism is used.) There's also a third register which indicates the current "top of stack."
At the beginning of executing each new function, the "top of stack" is simply moved ahead to account for the local variables, after the "local variables pointer" remembers what it used to be.
When a "return from subroutine" occurs, the "top-of-stack pointer" is reverted to some previous value, and everything that once existed "above it" is now, literally, forgotten. Because it no longer matters.
So, how are those(callstack, stack) related at all ?
They are very much related. They are the same thing. It is also called the execution stack.
This "callstack" is not to be confused with the general concept of "stack" data structure. The callstack called a stack because that describes the structure of the callstack.
causes call stack size to increase by 1
By "1" sure, but what it the unit of the increase? When you call a function, the stack pointer is incremented one stack frame. And the size (measured in bytes) of the stack frame varies. The frame of a function is big enough to contain all local variables (the parameters may also be stored on the stack).
So, if you wish to measure the increment in bytes, then it is not 1, but some number greater than or equal to 0.
I'd say that even creating local variables also causes call stack to be increased by 1.
As I described, having a local variable affects how the stack pointer is incremented when the function is called.
When we call nice, completely new stack gets created.
No, the same stack is shared by all function calls in the entire thread of execution.
Pretty much none of this is specified by the C++ language, but rather are implementation details that apply to most C++ implementations in typical case, but are simplified for easier understanding.
Stack denotes a data structure which consists of a set of usually similar items and has the following abilities:
push: adds an item to the "top" of the stack, which will become the new top
pop: removes the item from the top, thus the item which was previously the top will be the top again; this operation returns the item you remove
top: gets the top item of the stack, without modifying your stack
Your memory has a section called "the stack", where, as you correctly understood, functions are stored. That is the call stack. However, stack and call stack are not 100% equivalent, since stacks are used in many other cases, basically whenever you need a LIFO (Last In First Out) processing. It's used at the LIFO policy of the CPU, for example, or, when you do a depth-first search in a graph. In short, stack is a data structure, which can be applied in many cases, the call stack in memory being a prominent example.
So, why stack is in use to store function calls in memory. Let's take into consideration embedded function calls, like:
f1(f2(...(fn(x))...))
It's a rule of thumb that in order to evaluate fi, 1 <= i < n, you need to evaluate fj, where 1 < j <= n, assuming that i < j. As a result, f1 is the first to be called, but the last to be evaluated. Hence, you have a LIFO processing, which is best done via using a stack.

How does the stack hold variable values if they are stored in a LIFO structure?

I am slightly confused on how a compiler stores variable on the stack. I read that c++ can store local variables on the stack, but if the stack is LIFO, how could it make sure to call the right variable when the variable is called in the program?
The run-time stack isn't simply a LIFO structure; it's a complex structure which supports random access.
Typically how it works on many platforms is that whe na function is entered, a new stack frame is pushed onto the stack (LIFO fashion). Local variables are stored within the frame and are accessed relative to a more or less stable pointer stored in a register.
When other functions are called, they push their own frames, but they restore everything before returning.
Run-time stacks also typically support the ad hoc pushing and popping of individual values, for the purpose of temporarily saving register values or for parameter passing.
A common implementation strategy for that is to allocate the frame first. For instance if a 512 byte stack frame is needed, the stack pointer is moved by 512 bytes. The stack pointer is then used freely for pushing and popping, provided it doesn't pop too far and start gobbling into the frame.
A separate frame pointer may be used which tracks the location of the frame. The frame is then accessed relative to that frame pointer, which allows the stack pointer to move without interfering with those accesses.
Compilers can generate code without the use of frame pointers also; if the stack pointer only moves in ways that a compiler knows about, it can adjust all the variable references. Over an area of the code where the compiler knows that the stack pointer has moved by four bytes due to something being pushed on it, it can adjust the stack-pointer-relative frame references by four bytes.
The basic principle is that when a given function is executing, then the stack is in the right state that is expected by that function (unless something has gone horribly wrong due to a bug causing corruption or something). The LIFO allocation strategy of the stack frames closely tracks the function calls and returns. Functions that are called must save and restore certain registers (the "callee-saved registers"), which helps to maintain the stable stack environment.

C++ how are variables accessed in memory?

When I create a new variable in a C++ program, eg a char:
char c = 'a';
how does C++ then have access to this variable in memory? I would imagine that it would need to store the memory location of the variable, but then that would require a pointer variable, and this pointer would again need to be accessed.
See the docs:
When a variable is declared, the memory needed to store its value is
assigned a specific location in memory (its memory address).
Generally, C++ programs do not actively decide the exact memory
addresses where its variables are stored. Fortunately, that task is
left to the environment where the program is run - generally, an
operating system that decides the particular memory locations on
runtime. However, it may be useful for a program to be able to obtain
the address of a variable during runtime in order to access data cells
that are at a certain position relative to it.
You can also refer this article on Variables and Memory
The Stack
The stack is where local variables and function parameters reside. It
is called a stack because it follows the last-in, first-out principle.
As data is added or pushed to the stack, it grows, and when data is
removed or popped it shrinks. In reality, memory addresses are not
physically moved around every time data is pushed or popped from the
stack, instead the stack pointer, which as the name implies points to
the memory address at the top of the stack, moves up and down.
Everything below this address is considered to be on the stack and
usable, whereas everything above it is off the stack, and invalid.
This is all accomplished automatically by the operating system, and as
a result it is sometimes also called automatic memory. On the
extremely rare occasions that one needs to be able to explicitly
invoke this type of memory, the C++ key word auto can be used.
Normally, one declares variables on the stack like this:
void func () {
int i; float x[100];
...
}
Variables that are declared on the stack are only valid within the
scope of their declaration. That means when the function func() listed
above returns, i and x will no longer be accessible or valid.
There is another limitation to variables that are placed on the stack:
the operating system only allocates a certain amount of space to the
stack. As each part of a program that is being executed comes into
scope, the operating system allocates the appropriate amount of memory
that is required to hold all the local variables on the stack. If this
is greater than the amount of memory that the OS has allowed for the
total size of the stack, then the program will crash. While the
maximum size of the stack can sometimes be changed by compile time
parameters, it is usually fairly small, and nowhere near the total
amount of RAM available on a machine.
Assuming this is a local variable, then this variable is allocated on the stack - i.e. in the RAM. The compiler keeps track of the variable offset on the stack. In the basic scenario, in case any computation is then performed with the variable, it is moved to one of the processor's registers and the CPU performs the computation. Afterwards the result is returned back to the RAM. Modern processors keep whole stack frames in the registers and have multiple levels of registers, so it can get quite complex.
Please note the "c" name is no more mentioned in the binary (unless you have debugging symbols). The binary only then works with the memory locations. E.g. it would look like this (simple addition):
a = b + c
take value of memory offset 1 and put it in the register 1
take value of memory offset 2 and put in in the register 2
sum registers 1 and 2 and store the result in register 3
copy the register 3 to memory location 3
The binary doesn't know "a", "b" or "c". The compiler just said "a is in memory 1, b is in memory 2, c is in memory 3". And the CPU just blindly executes the commands the compiler has generated.
C++ itself (or, the compiler) would have access to this variable in terms of the program structure, represented as a data structure. Perhaps you're asking how other parts in the program would have access to it at run time.
The answer is that it varies. It can be stored either in a register, on the stack, on the heap, or in the data/bss sections (global/static variables), depending on its context and the platform it was compiled for: If you needed to pass it around by reference (or pointer) to other functions, then it would likely be stored on the stack. If you only need it in the context of your function, it would probably be handled in a register. If it's a member variable of an object on the heap, then it's on the heap, and you reference it by an offset into the object. If it's a global/static variable, then its address is determined once the program is fully loaded into memory.
C++ eventually compiles down to machine language, and often runs within the context of an operating system, so you might want to brush up a bit on Assembly basics, or even some OS principles, to better understand what's going on under the hood.
Lets say our program starts with a stack address of 4000000
When, you call a function, depending how much stack you use, it will "allocate it" like this
Let's say we have 2 ints (8bytes)
int function()
{
int a = 0;
int b = 0;
}
then whats gonna happen in assembly is
MOV EBP,ESP //Here we store the original value of the stack address (4000000) in EBP, and we restore it at the end of the function back to 4000000
SUB ESP, 8 //here we "allocate" 8 bytes in the stack, which basically just decreases the ESP addr by 8
so our ESP address was changed from
4000000
to
3999992
that's how the program knows knows the stack addresss for the first int is "3999992" and the second int is from 3999996 to 4000000
Even tho this pretty much has nothing to do with the compiler, it's really important to know because when you know how stack is "allocated", you realize how cheap it is to do things like
char my_array[20000];
since all it's doing is just doing sub esp, 20000 which is a single assembly instruction
but if u actually use all those bytes like memset(my_array,20000) that's a different history.
how does C++ then have access to this variable in memory?
It doesn't!
Your computer does, and it is instructed on how to do that by loading the location of the variable in memory into a register. This is all handled by assembly language. I shan't go into the details here of how such languages work (you can look it up!) but this is rather the purpose of a C++ compiler: to turn an abstract, high-level set of "instructions" into actual technical instructions that a computer can understand and execute. You could sort of say that assembly programs contain a lot of pointers, though most of them are literals rather than "variables".

a stack vs the stack and a heap vs the heap

I'm studying for my data organization final and I'm going over stacks and heaps because I know they will be on the final and I'm going to need to know the differences.
I know what the Stack is and what the Heap is.
But I'm confused on what a stack is and what a heap is.
The Stack is a place in the RAM where memory is stored, if it runs out of space, a stackoverflow occurs. Objects are stored here by default, it reallocates memory when objects go out of scope, and it is faster.
The Heap is a place in the RAM where memory is stored, if it runs out of space, the OS will assign it more. For an object to be stored on the Heap it needs to be told by using the, new, operator, and will only be deallocated if told. fragmentation problems can occur, it is slower then the Stack, and it handles large amounts of memory better.
But what is a stack, and what is a heap? is it the way memory is stored? for example a static array or static vector is a stack type and a dynamic array, linked list a heap type?
Thank you all!
"The stack" and "the heap" are memory lumps used in a specific way by a program or operating system. For example, the call stack can hold data pertaining to function calls and the heap is a region of memory specifically used for dynamically allocating space.
Contrast these with stack and heap data structures.
A stack can be thought of as an array where the last element in will be the first element out. Operations on this are called push and pop.
A heap is a data structure that represents a special type of graph where each node's value is greater than that of the node's children.
On a side note, keep in mind that "the stack" or "the heap" or any of the stack/heap data structures are unique to any given programming language but are simply concepts in the field of computer science.
I won't get into virtual memory (read about that if you want) so let's simplify and say you have RAM of some size.
You have your code with static initialized data, with some static uninitialized data (static in C++ means like global vars). You have your code.
When you compile something compiler (and linker) will organize and translate your code to machine code (byte code, ones and zeroes) in a following way:
Binary file (and object files) is organized into segments (portions of RAM).
First you have DATA segment. This is the segment that contains values of initialized variables. so if u have variables i.e. int a=3, b = 4 they will go to DATA segment (4 bytes of RAM containing 00000003h, and other 4 bytes containing 000000004h, hexadecimal notation). They are stored consecutively.
Then you have Code segment. All your code is translated into machine code (1s and 0s) and stored in this segment consecutively.
Then you have BSS segment. There goes uninitialized global vars (all static vars that weren't initialized).
Then you have STACK segment. This is reserved for stack. Stack size is determined by operating system by default. You can change this value but i won't get into this now. All local variables go here. When you call some function first func args are pushed to stack, then return address (where to come back when u exit function), then some computer registers are pushed here, and finally all local variables declared in the function get their reserved space on stack.
And you have HEAP segment. This is part of the RAM (size is also determined by OS) where the objects and data are stored using operator new.
Then all of the segments are piled one after the other DATA, CODE, BSS, STACK, HEAP. There are some other segments, but they are not of interest here, and that is loaded in RAM by the operating system. Binary file also has some headers containing information from which location (address in memory) your code begins.
So in short, they are all parts of RAM, since everything that is being executed is loaded into RAM (can't be in ROM (read only), nor HDD since HDD its just for storing files.
When specifically referring to C++'s memory model, the heap and stack refer to areas of memory. It is easy to confuse this with the stack data structure and heap data structure. They are, however, separate concepts.
When discussing programming languages, stack memory is called 'the stack' because it behaves like a stack data structure. The heap is a bit of a misnomer, as it does not necessarily (or likely) use a heap data structure. See Why are two different concepts both called "heap"? for a discussion of why C++'s heap and the data structure's names are the same, despite being two different concepts.
So to answer your question, it depends on the context. In the context of programming languages and memory management, the heap and stack refer to areas of memory with specific properties. Otherwise, they refer to specific data structures.
The technical definition of "a stack" is a Last In, First Out (LIFO) data structure where data is pushed onto and pulled off of the top. Just like with a stack of plates in the real world, you wouldn't pull one out from the middle or bottom, you [usually] wouldn't pull data out of the middle of or the bottom of a data structure stack. When someone talks about the stack in terms of programming, it can often (but not always) mean the hardware stack, which is controlled by the stack pointer register in the CPU.
As far as "a heap" goes, that generally becomes much more nebulous in terms of a definition everyone can agree on. The best definition is likely "a large amount of free memory from which space is allocated for dynamic memory management." In other words, when you need new memory, be it for an array, or an object created with the new operator, it comes from a heap that the OS has reserved for your program. This is "the heap" from the POV of your program, but just "a heap" from the POV of the OS.
The important thing for you to know about stacks is the relationship between the stack and function/method calls. Every function call reserves space on the stack, called a stack frame. This space contains your auto variables (the ones declared inside the function body). When you exit from the function, the stack frame and all the auto variables it contains disappear.
This mechanism is very cheap in terms of CPU resources used, but the lifetime of these stack-allocated variables is obviously limited by the scope of the function.
Memory allocations (objects) on the heap, on the other hand, can live "forever" or as long as you need them without regards to the flow of control of your program. The down side is since you don't get automatic lifetime management of these heap allocated objects, you have to either 1) manage the lifetime yourself, or 2) use special mechanisms like smart pointers to manage the lifetime of these objects. If you get it wrong your program has memory leaks, or access data that may change unexpectedly.
Re: Your question about A stack vs THE stack: When you are using multiple threads, each thread has a separate stack so that each thread can flow into and out of functions/methods independently. Most single threaded programs have only one stack: "the stack" in common terminology.
Likewise for heaps. If you have a special need, it is possible to allocate multiple heaps and choose at allocation time which heap should be used. This is much less common (and a much more complicated topic than I have mentioned here.)

What do C++ arrays init to?

So I can fix this manually so it isn't an urgent question but I thought it was really strange:
Here is the entirety of my code before the weird thing that happens:
int main(int argc, char** arg) {
int memory[100];
int loadCounter = 0;
bool getInput = true;
print_memory(memory);
and then some other unrelated stuff.
The print memory just prints the array which should've initialized to all zero's but instead the first few numbers are:
+1606636544 +32767 +1606418432 +32767 +1856227894 +1212071026 +1790564758 +813168429 +0000 +0000
(the plus and the filler zeros are just for formatting since all the numbers are supposed to be from 0-1000 once the array is filled. The rest of the list is zeros)
It also isn't memory leaking because I tried initializing a different array variable and on the first run it also gave me a ton of weird numbers. Why is this happening?
Since you asked "What do C++ arrays init to?", the answer is they init to whatever happens to be in the memory they have been allocated at the time they come into scope.
I.e. they are not initialized.
Do note that some compilers will initialize stack variables to zero in debug builds; this can lead to nasty, randomly occurring issues once you start doing release builds.
The array you are using is stack allocated:
int memory[100];
When the particular function scope exits (In this case main) or returns, the memory will be reclaimed and it will not leak. This is how stack allocated memory works. In this case you allocated 100 integers (32 bits each on my compiler) on the stack as opposed to on the heap. A heap allocation is just somewhere else in memory hopefully far far away from the stack. Anyways, heap allocated memory has a chance for leaking. Low level Plain Old Data allocated on the stack (like you wrote in your code) won't leak.
The reason you got random values in your function was probably because you didn't initialize the data in the 'memory' array of integers. In release mode the application or the C runtime (in windows at least) will not take care of initializing that memory to a known base value. So the memory that is in the array is memory left over from last time the stack was using that memory. It could be a few milli-seconds old (most likely) to a few seconds old (less likely) to a few minutes old (way less likely). Anyways, it's considered garbage memory and it's to be avoided at all costs.
The problem is we don't know what is in your function called print_memory. But if that function doesn't alter the memory in any ways, than that would explain why you are getting seemingly random values. You need to initialize those values to something first before using them. I like to declare my stack based buffers like this:
int memory[100] = {0};
That's a shortcut for the compiler to fill the entire array with zero's.
It works for strings and any other basic data type too:
char MyName[100] = {0};
float NoMoney[100] = {0};
Not sure what compiler you are using, but if you are using a microsoft compiler with visual studio you should be just fine.
In addition to other answers, consider this: What is an array?
In managed languages, such as Java or C#, you work with high-level abstractions. C and C++ don't provide abstractions (I mean hardware abstractions, not language abstractions like OO features). They are dessigned to work close to metal that is, the language uses the hardware directly (Memory in this case) without abstractions.
That means when you declare a local variable, int a for example, what the compiler does is to say "Ok, im going to interpret the chunk of memory [A,A + sizeof(int)] as an integer, which I call 'a'" (Where A is the offset between the beginning of that chunk and the start address of function's stack frame).
As you can see, the compiler only "assigns" memory-segments to variables. It does not do any "magic", like "creating" variables. You have to understand that your code is executed in a machine, and the machine has only a memory and a CPU. There is no magic.
So what is the value of a variable when the function execution starts? The value represented with the data which the chunk of memory of the variable has. Commonly, that data has no sense from our current point of view (Could be part of the data used previously by a string, for example), so when you access that variable you get extrange values. Thats what we call "garbage": Data previously written which has no sense in our context.
The same applies to an array: An array is only a bigger chunk of memory, with enough space to fit all the values of the array: [A,A + (length of the array)*sizeof(type of array elements)]. So as in the variable case, the memory contains garbage.
Commonly you want to initialize an array with a set of values during its declaration. You could achieve that using an initialiser list:
int array[] = {1,2,3,4};
In that case, the compiler adds code to the function to initialize the memory-chunk which the array is with that values.
Sidenote: Non-POD types and static storage
The things explained above only applies to POD types such as basic types and arrays of basic types. With non-POD types like classes the compiler adds calls to the constructor of the variables, which are designed to initialise the values (attributes) of a class instance.
In addition, even if you use POD types, if variables have static storage specification, the compiler initializes its memory with a default value, because static variables are allocated at program start.
the local variable on stack is not initialized in c/c++. c/c++ is designed to be fast so it doesn't zero stack on function calls.
Before main() runs, the language runtime sets up the environment. Exactly what it's doing you'd have to discover by breaking at the load module's entry point and watching the stack pointer, but at any rate your stack space on entering main is not guaranteed clean.
Anything that needs clean stack or malloc or new space gets to clean it itself. Plenty of things don't. C[++] isn't in the business of doing unnecessary things. In C++ a class object can have non-trivial constructors that run implicitly, those guarantee the object's set up for use, but arrays and plain scalars don't have constructors, if you want an inital value you have to declare an initializer.