Originally created by Jerrett Longworth and Idel Martinez in Fall 2020.
Let’s take a look at one of the craziest concepts we have in our toolkit to date: dynamically-allocated memory.
typedef struct Computer
{
int memory;
int processes;
float power;
} Computer;
int main(void)
{
*my_PC = malloc(sizeof(Computer));
Computer
("Hello, world!\n");
printf
return 0;
}
Answer: Nope, we’re missing free(my_PC)
so memory is getting leaked!
true
? What will print out in this
program?typedef struct Computer
{
int memory;
int processes;
float power;
} Computer;
*copy_struct(Computer *pc)
Computer {
*temp = malloc(sizeof(Computer));
Computer ->memory = pc->memory;
temp->processes = pc->processes;
temp->power = pc->power;
temp
return temp;
}
int main(void)
{
*my_PC = malloc(sizeof(Computer));
Computer *my_other_PC;
Computer
->memory = 10000;
my_PC->processes = 29;
my_PC->power = 79.81;
my_PC= copy_struct(my_PC);
my_other_PC
if (my_PC == my_other_PC)
{
("Now my PC and my other PC are equal!\n");
printf}
else
{
("MEM: %d vs %d\n", my_PC->memory, my_other_PC->memory);
printf("PRO: %d vs %d\n", my_PC->processes, my_other_PC->processes);
printf("POW: %.2f vs %.2f\n", my_PC->power, my_other_PC->power);
printf}
(my_PC);
free(my_other_PC);
free
return 0;
}
Answer: The structs are equal, but the conditional
is false since they are NOT pointing to the same address. You will see
that the values that print out will be the same for my_PC
and my_other_PC
, since they are equal but independent -
this is why we free
twice.
true
? Also, what is missing from this
program regarding memory management?typedef struct Computer
{
int memory;
int processes;
float power;
} Computer;
*copy_struct(Computer *pc)
Computer {
*temp = pc;
Computer
return temp;
}
int main(void)
{
*my_PC = malloc(sizeof(Computer));
Computer *my_other_PC = copy_struct(my_PC);
Computer
if (my_PC == my_other_PC)
("Now my PC and my other PC are equal!\n");
printf
return 0;
}
Answer: Notice how the copy_struct
function, different from the previous exercise, is setting one pointer
to be my_PC
. Therefore, both pointers will be pointing to
the same address and the conditional is true. Notice also that we are
missing the free
… oh no!
typedef struct Computer
{
int memory;
int processes;
float power;
} Computer;
*copy_struct(Computer *pc)
Computer {
*temp = pc;
Computer
return temp;
}
int main(void)
{
*my_PC = malloc(sizeof(Computer));
Computer *my_other_PC = copy_struct(my_PC);
Computer
(my_PC);
free(my_other_PC);
free
return 0;
}
Answer: Similar to the previous exercise,
my_PC
and my_other_PC
are pointing to the same
address (they are equal to each other). This means that when we free one
of the pointers, we freed the memory they were pointing to and it would
be incorrect to try to free
again, since it had been
free
d before.
power
for both my_PC
and my_other_PC
?typedef struct Computer
{
int memory;
int processes;
float power;
} Computer;
*copy_struct(Computer *pc)
Computer {
*temp = pc;
Computer ->power = 100;
temp
return temp;
}
int main(void)
{
*my_PC = malloc(sizeof(Computer));
Computer ->power = 79.81;
my_PC*my_other_PC = copy_struct(my_PC);
Computer
(my_PC);
free(my_other_PC);
free
return 0;
}
Answer: Once again, copy_struct
is
setting the pointers equal to each other so that they are pointing to
the same address. This means that any changes to one pointer will also
be reflected on the other pointer, so the value of power
is
100 for both. Notice also that we should not be using
free()
twice. Can you see why?
Pixel
struct with the red, green, and
blue components. (1) Create an array of 1024
pixels
dynamically, (2) assign values to each pixel, and (3)
free the memory associated with the array.Answer:
typedef struct Pixel
{
int r;
int g;
int b;
} Pixel;
int main(void)
{
*scan_line;
Pixel int n = 1024;
(time(NULL));
srand
// Create an array of pixels. Your code goes here
= malloc(sizeof(Pixel) * n);
scan_line
for (int i = 0; i < n; i++)
{
// Your code goes here
[i].r = rand() % 256;
scan_line[i].g = rand() % 256;
scan_line[i].b = rand() % 256;
scan_line}
// Time to free. Your code goes here
(scan_line);
free
return 0;
}
Answer:
typedef struct Birthday
{
int day;
int year;
char month[10];
} Birthday;
typedef struct Person
{
char *name;
int age;
;
Birthday birthday} Person;
int main(void)
{
*human = malloc(sizeof(Person));
Person int name_length = 14; // or better yet: strlen("Adele Goldberg")
->name = malloc(sizeof(char) * (name_length + 1));
human
// Your code goes here
(human->name, "Adele Goldberg");
strcpy->age = 75;
human
->birthday.day = 22;
human->birthday.year = 1945;
human(human->birthday.month, "July");
strcpy
("Hello, I am %s, a %d-year-old.\n", human->name, human->age);
printf("I was born in %s, %d, %d\n", human->birthday.month, human->birthday.day, human->birthday.year);
printf
(human);
free
return 0;
}
Crazy advanced answer using user input and more pointers:
typedef struct Birthday
{
int day;
int year;
char month[10];
} Birthday;
typedef struct Person
{
char *name;
int age;
*birthday;
Birthday } Person;
*create_person(char *name, int name_length)
Person {
*person = malloc(sizeof(Person));
Person
->name = malloc(sizeof(char) * (name_length + 1));
person(person->name, name);
strcpy->age = 100;
person
->birthday = malloc(sizeof(Birthday));
person->birthday->day = 1;
person->birthday->year = 1900;
person(person->birthday->month, "January");
strcpy
return person;
}
void free_person(Person *person)
{
if (person == NULL)
return;
(person->name);
free(person->birthday);
free(person);
free}
int main(void)
{
*human = NULL;
Person int name_length;
char buffer[1024];
("What is your name? ");
printf("%s", buffer);
scanf
= strlen(buffer);
name_length = create_person(buffer, name_length);
human
("Hello, I am %s, a %d-year-old.\n", human->name, human->age);
printf("I was born in %s, %d, %d\n", human->birthday->month, human->birthday->day, human->birthday->year);
printf
(human);
free_person
return 0;
}
calloc()
typedef struct Computer
{
int memory;
int processes;
float power;
} Computer;
int main(void)
{
Computer *my_PC = calloc(1, sizeof(Computer));
Computer *my_other_PC = malloc(sizeof(Computer));
printf("%d\n", my_PC->memory + my_PC->processes + my_PC->power);
printf("%d\n", my_other_PC->memory + my_other_PC->processes + my_other_PC->power);
free(my_PC);
free(my_other_PC);
return 0;
}
Answer: Because calloc
sets initial
values to the struct, my_PC members are all 0. malloc
doesn’t do anything to do values and can can be garbage values. So, line
13 prints 0 and line 14 prints garbage values.