# Dive Into Systems: Exercises

## Section2.4Dynamic Memory Allocation

### Checkpoint2.4.1.Dynamic Memory Allocation.

What is the difference between arr1 and arr2, defined as follows?
        int arr1;
int *arr2;

arr2  =  (int *) malloc(sizeof(int) * 10);

• They are different sizes.
• No. Both arr1 and arr2 can hold up to 10 int elements.
• arr1 is allocated in stack memory, while arr2 is allocated in heap memory.
• Correct!
• arr1 stores ints, while arr2 stores pointers to ints.
• Incorrect. Read the code again carefully!
• arr1 is NULL, but arr2 contains values.
• Incorrect. Neither array contains any values.

### Checkpoint2.4.2.Dynamic Memory Allocation (Q2).

Why might one choose to allocate an array dynamically in heap memory using malloc rather than statically in stack memory? Select all that apply.
• You want to avoid exceeding the size of stack memory.
• Correct! The stack is of limited size.
• The size of the array is not known until runtime.
• Great work!
• You want to provide more flexibility to grow or shrink the size of the array.
• Correct! Unlike static arrays, you can change the size of a dynamically allocated array!
• To automatically deallocate the array when the function returns.
• Incorrect!

### Checkpoint2.4.3.Dynamic Memory Allocation (Q3).

Given the function prototype:
void *test_fun(int i);
What is the meaning of void *?
• test_fun returns a pointer to an unspecified type
• Correct!
• test_fun does not return a value
• Incorrect.
• test_fun returns NULL
• Incorrect.

### Checkpoint2.4.4.Dynamic Memory Allocation (Active Code).

In the main function, 1.) write code to declare a static array named static_array with a fixed size of 5 integers. Similarly, 2.) write code to dynamically allocate an array named dynamic_array that will be used to store 5 integers. Finally, initialize the values in both arrays to be [1, 2, 3, 4, 5].
#include <stdio.h>

int main(void) {

//write code to declare a static array named static_array

//write code to dynamically allocate an array named dynamic_array

//initialize the values in both arrays to be [1,2,3,4,5]

return 0;
}

A sample implementation is shown below:
int static_array;
int *dynamic_array;
int i;

// allocate heap space for dynamic_array
dynamic_array = (int *) malloc(sizeof(int) * 5);

// Initialize arrays with values 1 to size
for (i = 0; i < 5; i++) {
static_array[i] = i + 1;
dynamic_array[i] = i + 1;
}


### Checkpoint2.4.5.Dynamic Memory Allocation (Q4).

Given the following code, which of the calls to do_something are valid? Select all that apply.
void do_something(int *array, int size);

int arr1;
int *arr2;

arr2 = malloc(sizeof(int)*10);

// assume some initialization code is here

// call do_something here

• do_something(arr1, 10);
• Correct!
• do_something(arr2, 10);
• Correct!
• do_something(&arr1, 10);
• Incorrect.
• do_something(&arr2, 10);
• Incorrect.

### Checkpoint2.4.6.Dynamic Memory Allocation (Active Code).

Write a function that receives an array of int and its size as its two parameters and prints all the elements in the array.
#include <stdio.h>


A sample solution is shown below:
       //void print_array(int *array, int size) { //is also valid
void print_array(int array[], int size) {
int i;

for (i = 0; i < size; i++) {
printf("%d ", array[i]);
}
}


### Checkpoint2.4.7.Fill In The Blank.

Given the code:
void init_array(double *array, int size);

int main(void) {
int size;
double *array2;

size = 100;
array2  = (double *) malloc(sizeof(double) * size);
array2 = 2.0;
init_array(array2, size);
printf(“%f\n”, array2);
}

void init_array(double *array, int size){

array  = (double *) malloc(sizeof(double) * size);
array = 3.0;
}

What will main print out?

### Checkpoint2.4.8.Explore a larger program.

Consider the execution of the mallocstacktrace.c program:
#include <stdio.h>
#include <stdlib.h>

void foo(int *b, int c, int *arr, int n) ;
void blah(int *r, int s);

int main(void) {
int x, y, *arr;

arr = (int *)malloc(sizeof(int)*5);
if (arr == NULL) {
exit(1);   // should print out nice error msg first
}

x = 10;
y = 20;
printf("x = %d y = %d\n", x, y);
foo(&x, y, arr, 5);
printf("x = %d y = %d arr = %d arr = %d\n",
x, y, arr,arr);
free(arr);

return 0;
}

void foo(int *b, int c, int *arr, int n) {
int i;
c = 2;
for (i=0; i<n; i++) {
arr[i] = i + c;
}
*arr = 13;
blah(b, c);
}

void blah(int *r, int s) {
*r = 3;
s = 4;
// DRAW STACK HERE
}


#### (a)

Step through the execution of this program. What is its output?
The program’s output is:
x = 10 y = 20
x = 3 y = 20 arr = 13 arr = 5


#### (b)

List the values of the array’s elements after the call to foo returns.
13, 3, 4, 5, 6 