PR2EN8: Dynamic memory 2

Lab materials

Lab tasks

This lab has one task that is extended by 2 advanced tasks

Lab task: Reading a file dynamically

The purpose of this task is to introduce how to read an unknown length file and allocate the structure array for it dynamically in the exact length required.

Data file

Data file structure for the task: <index> <last name> <first name> <curriculum code> <points>

  • Index (integer)
  • First and last name – strings with varying length
  • Curriculum code – string with exactly 4 characters
  • Points – floating point value from 10.0 to 30.0 with a precision of 0.1.

You can use the data file generator from last week for this. To test, we’ve also provided files so you can compare your output.

Download data files here that we used in the testing part.: https://blue.pri.ee/ttu/files/iax0584/andmefailid/8_scholarship_data.zip

Requirements
  • Read an unknown length data file into memory
    • Use realloc() to read the data, expanding your memory as you are reading the file
    • Store the data into a dynamically created structure array
    • Once the reading is finished, you allocated memory size must match the exactly to how many were read from the file
    • You can only read the file once (repeat reading is forbidden, this includes just checking for newline count!)
    • The length of the file can change  – the exact length is determined during reading.
  • All variable length strings must be stored in memory exactly (using dynamic memory allocation).
    • During reading, use a static buffer and then use dynamic memory to store it into the struct.
  • The file contains students competing for a scholarship. Scholarships are given
    • For 7 best students (highest points count) for the following curriculums: IACB, EARB, MVEB
  • Print the list of students who will receive the scholarship and also print the number of students who got it from each curriculum.
  • Make sure there are no memory leaks!
Data structure for the task

For this task, we will transition into using dynamic memory for variable length strings (and other arrays) inside of our structure in order to save memory. The struct will now take the following form:

Note:

  • You can alter the naming to your liking.
  • The fName and lName are now pointers that need dynamic memory allocation due to the length being variable from person to person.
  • Array for curriculum stayed as static because it never changes – using dynamic memory here would be a waste.
  • Single ints, floats… remain static because again, using dynamic for those members would be making the program purposefully slower and more complex.
Recommended list of functions

NB! The actual form the functions take depends on how you tackle the task.

At minimum, you need three functions:

  • Reading the data (check the next subheading).
  • Printing the results.
  • Freeing the memory.

Recommended functions to make your life easier

  • qsordi compare function
  • Printing the data of a single student (useful for printing the students who get the scholarship).
  • For defensive programming, the function shown on the slides

To make sure everything got into the memory fine, you might want to have a function that just prints everyone data. This is however not a part of the task.

Updates to reading a file function

From now, the reading function takes a new form. We need to get 2 values from the reading function – location of the array and number of lines. I’m proposing a three options for this  different function.

First variant will return the number of lines and passes the location of the memory as a double pointer.

Second variant returns the pointer to the allocated array and passes the line number through a pointer.

I’m also proposing a third option. The benefit in this one is that the function can convey information about the status of the reading to the caller (e.g. successful read, error reading). If you want, you can add more codes to be more precise on the errors.

Testing

In the first file, we’re using the longer data file where all scholarships got assigned. Notice the heap summary!

In the second example, I’m using the shorter data file.

Advanced task 1: Optimal algorithms for allocation

In this task we’re changing the algorithm how we are allocating memory to a more reasonable one.

Requirements
  • Change the file reading in a way that you would be using the (n * 2) expansion strategy
    • Every time you run out of memory, you reallocate to a 2x higher amount that you have right now.
  • To start, pick an initial allocation that is greater than 1 (pick a size that would be 3x lower than the file length just so you can observe the correctness).

Advanced task 2: wrapper struct

In this task, we’re making our code a bit more readable and contained. We will put both the struct and its properties into a wrapper to keep everything tightly integrated.

Requirements
  • Put your structure array pointer into the other struct (wrapper)
  • In your wrapper, you should have 3 variables – pointer to the struct, number of structs allocated, number of structs used
  • Change your function parameters for the existing functions to use the new wrapper struct
  • NB! Think through for which functions it is required to pass a pointer to the wrapper where it is unnecessary.

Hint: Now you will need an extra access layer to get from the wrapper to the struct itself. To help with readability, you might want to “unpack” those variables when you need to use them. See the following example.

After this class, you should

  • know different ways to structure your code in order to read files that can be of any length
  • Know how to dynamically alter your array size
  • Know how to read data into an expanding array using dynamic memory allocation
  • know all possible ways realloc works
  • know the difference between (n + 1) and (n * 2) allocation strategies and be able to implemetn at least one of the two
  • be able to  allocate memory to members of structures
  • know about defensive programming idea for freeing memory
  • Know all the steps strdup() does in the background and be able to use it.

Additional materials