Here is a sample program that declares a few local, global, static variables, arrays, consts and also allocates memory dynamically. It prints out the addresses of the variables, the string literal and dynamically allocated memory. Include your favorite headers to compile :-)
const int a = 0;
char *b = "String Literal";
int c;
char d[10];
static int e;
void main()
{
static int f;
int g;
int h[2];
const int i= 0;
int *j = (int*) malloc(sizeof(int));
int *k = new int;
printf("// global constant & string literal\n");
printf(" const int a \t%d\n char *b \t%d\n\n", &a, b);
printf("// global variable, global array, static variables\n");
printf(" int c \t\t%d\n char d[] \t%d\n static int e \t%d\n static int f \t%d\n\n", &c, d, &e, &f);
printf("// local variable, local array, local const\n");
printf(" int g \t\t%d\n int h[] \t%d\n const int i \t%d\n\n", &g, h, &i);
printf("// malloc, new\n");
printf(" int *j \t%d\n int *k \t%d\n\n", j, k);
free(j);
delete k;
}
The output of the above program on a Windows machine would look like this (the addresses would be different on a different machine):

Looking at the addresses printed, it can be said that:
* Global constants and String literals are stored together. Further, the memory they are stored in is read-only and any write operation will cause a runtime error!
* Global variables and static variables (even if they are declared as static inside a function) are stored together. They are placed in a memory region that is initialized at the beginning of the process and is maintained till the end of the process.
* malloc function and new operator dynamically allocate memory from another section called Heap.
* Local variables are stored in yet another location called Stack.
Interestingly, even the constants defined within a function go onto the Stack. However, there is no read-only section on the Stack. Which means the local variable defined as "const" inside a function is not really protected againt write operations the way the global consts are protected. So, you could still modify the "const int" defined inside a function by assigning its address to an int * and typecasting it as such like below:
void foo()
{
const int i = 0;
// Typecast to avoid the compiler error.
int *j = (int *) &i;
// You can actually modify the const! Now try making "i" global.
*j = 1;
printf("%d\n", *j);
}
Wondering why I chose to use *j instead of i in the printf()? That is because printf("%d\n", i) would still print 0! Can you guess why? That is because i is declared as const and the compiler replaces i with 0 (the initial value) when it generates the assembly. After all, it doesn't expect the code to modify a const!
No comments:
Post a Comment