The following 20 problems assume that you are familiar with the system calls to allocate and deallocate dynamic memory. The following basic data type sizes are assumed:
Type | Size (bytes) |
---|---|
char , unsigned char
| 1 |
short int , unsigned short int
| 2 |
int , unsigned int , long
int , unsigned long int
| 4 |
float | 4 |
double , long double
| 8 |
Pointer of any type | 4 |
To solve some of the following problems, consider the following C program as example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #include <stdlib.h> #include <string.h> #define MAC_LENGTH 6 struct bluetooth_info { char *name; unsigned int strength; char mac[MAC_LENGTH]; }; struct bluetooth_info info, *new_info; struct bluetooth_info *duplicate(struct bluetooth_info *); int main(int argc, char **argv) { struct bluetooth_info *info_ptr; int i; info_ptr = &info; info_ptr->name = "My phone"; info_ptr->strength = 100; for (i = 0; i < MAC_LENGTH; i++) { info_ptr->mac[i] = 10; } new_info = duplicate(info_ptr); free(new_info); return 0; } struct bluetooth_info *duplicate(struct bluetooth_info *src_ptr) { struct bluetooth_info *result; int i; result = (struct bluetooth_info *)malloc(sizeof(struct bluetooth_info)); result->name = (char *)malloc(strlen(src_ptr->name) + 1); strcpy(result->name, src_ptr->name); result->strength = src_ptr->strength; for (i = 0; i < MAC_LENGTH; i++) { result->mac[i] = src_ptr->mac[i]; } return result; } |
It is recommended that you download the program in your work area to make small changes, compile it and execute it. Some of the following problems can be solved this way.
What is the size of the structure defined in lines 6 to 11?
Why do you think line 15 is required? Try to comment it and compile the program.
In line 23 there is an assignment of a string, What type of memory (global, heap, stack) is this string using?
Rewrite lines 23 and 24 but use variable
info
instead of info_ptr
. Can you rewrite the
main
function maintaining its functionality but suppressing
the variable info_ptr
?
Search what exactly is the function strlen
doing when used in line 41. What is the result for the invocation in the
example program? How much memory is being reserved in that invocation of
malloc
?
Search what does the function strcpy
used in
line 42 and explain which memory is being modified and where is it for the
example program.
How would you access to the third letter of the string
stored in the field name
of the structure pointed to by
result
in line 43? (You may answer the question inserting a
line that prints your answer and executing the program)
Where is the value of the pointer result
copied when line 48 is executed?
How many bytes of dynamic memory are used in the example program?
Classify the following variables of the example program.
Line | Variable | Global Memory | Heap | Stack | No memory |
---|---|---|---|---|---|
6-11 | struct bluetooth_info | ||||
13 | info | ||||
13 | new_info | ||||
19 | info_ptr | ||||
20 | i | ||||
23 | info_ptr->name | ||||
24 | info_ptr->strength | ||||
35 | src_ptr | ||||
37 | result | ||||
38 | i | ||||
40 | malloc(sizeof(struct bluetooth_info)) | ||||
43 | result->strength |
The duplicate
function defined in lines 35 to
49, as the name suggest, creates a structure that is a duplicate of the
one pointed by the given parameter. In line 29 in the main
the duplicate is obtained invoking the function and its result is stored
in new_info
. What would be the effect if, instead of invoking
duplicate
the assignment is simply new_info =
info_ptr
?
The duplication of the field name
in the data
structure pointed by the parameter is done in lines 41 and 42. Why is it
not enough to write simply result->name =
src_ptr->name
?
How would you allocate space for an array of 200 elements
of the structure struct bluetooth_info
and at the same time
initialize all its content to the value zero? Assign the address of that
space to the pointer ptr
. Write an equivalent code portion
but using malloc
.
In a C program space in memory for a table containing 100
edata structures previously defined needs to be allocated but there is no
need to initialize them to any value. Which system call
malloc
or calloc
would you use? Why?
A program defines the following data structure in which an array of integers and an array of chars are stored but of unknown size:
struct two_tables { int *int_table; char *char_table; };
Write a function that receives two integers, reserves a
structure of this type with tables of the size given by the parameter
values and returns the pointer to this structure. No initialization is
required in the data. Hint: more than one call to malloc
is
required.
Write the opposite function, that is, given a pointer to one of this structure, frees the memory occupied by the structure and the tables.
How would you allocate memory space for a table of 100
elements of type struct two_tables
? How much space would occupy
in memory?
A graphic application maintains a table with a set of points represented as integers. The total number of points fluctuates in a range between zero and one million. To avoid having the memory reserved for one million points, the application starts reserving space only for 1000 points with the line:
points = (int *)malloc(1000 * sizeof(int));
The application keeps count of the points stored, but after a while executing, it needs to store more than 1000 points. Which operation on dynamic memory does it need to be executed? Which parameters would you use? Justify your answer.
An application stores the information about contacts in a table of 100 structures as the following one:
struct contact { char *name; char *lastname; };
The variable table
stores these elements and
the space has been dynamically reserved (either with malloc
or calloc
). Analogously, for each element, the space pointed
by the fields name
and lastname
has also been
dynamically reserved. Write a function that receives as parameters a
pointer to a table of this kind and integer with its number of elements,
and deallocates all the memory occupied by the table.
void nuke(struct contact *table, int size) { ... ... }
Suppose the following data structure definition, variable declaration an code:
struct unit { struct unit *next; } *unit1, *unit2, *unit3; unit1 = (struct unit *)malloc(sizeof(struct unit)); unit2 = (struct unit *)malloc(sizeof(struct unit)); unit3 = (struct unit *)malloc(sizeof(struct unit)); unit1->next = unit2; unit2->next = unit3; unit3->next = NULL;
Write the function void delete(struct unit
*ptr)
such that if invoked as delete(unit1)
it
de-allocates the memory reserved to all three structures. Do you have to
change anything in your function to perform the same operation over an
arbitrarily long chain of structures?
Let us assume that during a C program execution, each time
either malloc
or calloc
are invoked a global
variable (intialized to zero) in increased, and each time
free
is invoked the same variable is decreased:
What would be the value at the end of the program execution?
And if a program terminates its execution with this variable equal to zero, is this enough to conclude that the memory management is done correctly?
A C program manipulates a very large number of elements with the following two data structures:
struct picture_info { char *name; char *location; char *note; int size; int latitude; int longitude; }; struct video_info { char *location; int *encoding int length; };
All the elements are created using dinamic memory and the application code is prefectly divided into two parts, each of them to manipulate the elements in one of these structures.
Once the program terminates execution, there are certain memory portions that have been allocated but not freed. A tool is used to supervise this execution and at the end, a report is produced saying that a total of 2345 memory portions, all of them of 12 bytes, were allocated but not freed. In which part of the code would you start to look for the anomaly in the memory management and why?