Question
memory_segments.cpp. #include #include int g0; /* global variable, uninitialized */ int g1 = 14; /* global variable, initialized */ int g2[1500]; /* global variable, uninitialized
memory_segments.cpp.
#include
#include
int g0; /* global variable, uninitialized */
int g1 = 14; /* global variable, initialized */
int g2[1500]; /* global variable, uninitialized */
int g3 = 16; /* global variable, initialized */
int g4; /* global variable, uninitialized */
void proc1();
void proc2();
int main()
{
extern int etext[], edata[], end[];
int lc0; /* local variable, stored on stack */
int lc1 = 27; /* local variable, stored on stack; mix init and uninit */
int lc2; /* local variable, stored on stack */
static int ls0; /* local static variable, uninitialized data */
static int ls1 = 19; /* local static variable, initialized data */
int *pheap1;
int *pheap2;
pheap1 = (int *) malloc(sizeof(int));
pheap2 = (int *) malloc(sizeof(int));
printf(" ---------- main ------------------- ");
printf("%14p (%15lu): Last address ",
0xffffffffffff, 999999999999999);
printf("%14p (%15lu): Address etext ",
etext, etext);
printf("%14p (%15lu): Address edata ",
edata, edata);
printf("%14p (%15lu): Address end ",
end, end);
printf("%14p (%15lu): Address of code for proc1 ",
&proc1, &proc1);
printf("%14p (%15lu): Address of code for proc2 ",
&proc2, &proc2);
printf("%14p (%15lu): Address of uninitialized global variable g0 ",
&g0, &g0);
printf("%14p (%15lu): Address of initialized global variable g1 ",
&g1, &g1);
printf("%14p (%15lu): Address of uninitialized global array g2 ",
&g2[0], &g2[0]);
printf("%14p (%15lu): Address of initialized global variable g3 ",
&g3, &g3);
printf("%14p (%15lu): Address of uninitialized global variable g4 ",
&g4, &g4);
printf("%14p (%15lu): Address heap1 in heap space ",
pheap1, (unsigned long) pheap1);
printf("%14p (%15lu): Address heap2 in heap space ",
pheap2, (unsigned long) pheap2);
printf("%14p (%15lu): Address of local variable lc0 ",
&lc0, &lc0);
printf("%14p (%15lu): Address of local variable lc1 ",
&lc1, &lc1);
printf("%14p (%15lu): Address of local variable lc2 ",
&lc2, &lc2);
printf("%14p (%15lu): Address of local uninitialized static var ls0 ",
&ls0, &ls0);
printf("%14p (%15lu): Address of local initialized static var ls1 ",
&ls1, &ls1);
proc1();
proc2();
return 0;
}
void proc1() {
int lc3;
int lc4 = 37;
printf(" ----------- proc1 ------------------ ");
printf("%14p (%15lu): Address of code for proc1 ",
&proc1, &proc1);
printf("%14p (%15lu): Address of global variable g0 ",
&g0, &g0);
printf("%14p (%15lu): Address of global variable g1 ",
&g1, &g1);
printf("%14p (%15lu): Address of global variable g2 ",
&g2[0], &g2[0]);
printf("%14p (%15lu): Address of global variable g3 ",
&g3, &g3);
printf("%14p (%15lu): Address of global variable g4 ",
&g4, &g4);
printf("%14p (%15lu): Address of local variable lc3 ",
&lc3, &lc3);
printf("%14p (%15lu): Address of local variable lc4 ",
&lc4, &lc4);
}
void proc2() {
int lc5;
int lc6 = 51;
static int ls2;
static int ls3 = 47;
printf(" ------------ proc2 ----------------- ");
printf("%14p (%15lu): Address of code for proc2 ",
&proc2, &proc2);
printf("%14p (%15lu): Address of global variable g0 ",
&g0, &g0);
printf("%14p (%15lu): Address of global variable g1 ",
&g1, &g1);
printf("%14p (%15lu): Address of global variable g2 ",
&g2[0], &g2[0]);
printf("%14p (%15lu): Address of global variable g3 ",
&g3, &g3);
printf("%14p (%15lu): Address of global variable g4 ",
&g4, &g4);
printf("%14p (%15lu): Address of local variable lc5 ",
&lc5, &lc5);
printf("%14p (%15lu): Address of local variable lc6 ",
&lc6, &lc6);
printf("%14p (%15lu): Address of local uninitialized static var ls2 ",
&ls2, &ls2);
printf("%14p (%15lu): Address of local initialized static var ls3 ",
&ls3, &ls3);
}
memdiagram.txt
/* +------------------+ | TEXT | x10000? | | | instructions in | x10b10 = proc1 | machine code | x10be8 = proc2 | | +------------------+ x11489 = etext | DATA | x21698 = g1 global initialized | - initialized | x2169c = g3 | variables | x216a0 = ls1 static initialized | | x216a4 = ls3 | | | --------------- | x216a8 = edata | | x216a8 = g0 global uninitialized | | x216ac = g2 big array | | x226b0 = g4 | - uninitialized | x216b8 = ls0 static uninitialized | variables | x216bc = ls2 | | | | | --------------- | x22668 = end | - heap for | x22670 pointed to by heap1 | dynamic | x22680 pointed to by heap2 | allocation | | | | | +------------------+ | | V
. . .
^ | | +------------------+ | STACK | xffbef804 = lc4, lc6 | Activation record for | - function | xffbef808 = lc3, lc5 | proc1 or proc2 | activation | | records | | - local | xffbe2878 = lc2 | Activation record for | automatic | xffbe287c = lc1 | main | variables | xffbe2880 = lc0 | +------------------+ */
o local automatic variables from main o local automatic variables from each of proc1 and proc2 Copy the contents of the following link into a blank lab1.c file: memdiagram.txt You will change the addresses to match what you are seeing when you run memory_segments.cpp. Please remember to include the "etext", "edata", and "end" addresses 4. As variables are added to the stack, do the addresses get smaller or larger? 5. Do variables stored on the stack ever have the same address as other variables? Why or why not? 6. Where would you expect variables (or arguments) in recursive functions to be stored (stack, heap, or other data segment)? When you are finished step 7 below, comment on whether your expectations were correct or not. 7. Test your expectation by creating a recursive factorial function in lab1.c. For instance, the factorial of 5 is represented by 5! and is calculated as 5x4x3x2x1=120. In the factorial function, you will print the address of the factorial function and the address of the argument passed to it. In main, you will prompt the user for what factorial they will want to calculate and send that input as an argument to the function. In main, you will also print the value returned from the factorial function Note: you will be expected to use scanf and printf The idea behind the recursive factorial function is the following: Fn = { if n = 0 (base case) if n >= 1 (recursive step) n*Fn-1 o local automatic variables from main o local automatic variables from each of proc1 and proc2 Copy the contents of the following link into a blank lab1.c file: memdiagram.txt You will change the addresses to match what you are seeing when you run memory_segments.cpp. Please remember to include the "etext", "edata", and "end" addresses 4. As variables are added to the stack, do the addresses get smaller or larger? 5. Do variables stored on the stack ever have the same address as other variables? Why or why not? 6. Where would you expect variables (or arguments) in recursive functions to be stored (stack, heap, or other data segment)? When you are finished step 7 below, comment on whether your expectations were correct or not. 7. Test your expectation by creating a recursive factorial function in lab1.c. For instance, the factorial of 5 is represented by 5! and is calculated as 5x4x3x2x1=120. In the factorial function, you will print the address of the factorial function and the address of the argument passed to it. In main, you will prompt the user for what factorial they will want to calculate and send that input as an argument to the function. In main, you will also print the value returned from the factorial function Note: you will be expected to use scanf and printf The idea behind the recursive factorial function is the following: Fn = { if n = 0 (base case) if n >= 1 (recursive step) n*Fn-1Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started