{"id":8357,"date":"2023-03-19T23:17:57","date_gmt":"2023-03-19T21:17:57","guid":{"rendered":"https:\/\/blue.pri.ee\/ttu\/?p=8357"},"modified":"2026-03-22T20:18:58","modified_gmt":"2026-03-22T18:18:58","slug":"pr2en8-dynamic-memory-2","status":"publish","type":"post","link":"https:\/\/blue.pri.ee\/ttu\/labs\/pr2en8-dynamic-memory-2\/","title":{"rendered":"PR2EN8: Dynamic memory 2"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/blue.pri.ee\/ttu\/labs\/pr2en8-dynamic-memory-2\/#Lab_materials\" >Lab materials<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/blue.pri.ee\/ttu\/labs\/pr2en8-dynamic-memory-2\/#Lab_tasks\" >Lab tasks<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/blue.pri.ee\/ttu\/labs\/pr2en8-dynamic-memory-2\/#Lab_task_W08-1_Reading_a_file_dynamically\" >Lab task [W08-1]: Reading a file dynamically<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/blue.pri.ee\/ttu\/labs\/pr2en8-dynamic-memory-2\/#Data_file\" >Data file<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/blue.pri.ee\/ttu\/labs\/pr2en8-dynamic-memory-2\/#Requirements\" >Requirements<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/blue.pri.ee\/ttu\/labs\/pr2en8-dynamic-memory-2\/#Data_structure_for_the_task\" >Data structure for the task<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/blue.pri.ee\/ttu\/labs\/pr2en8-dynamic-memory-2\/#Recommended_list_of_functions\" >Recommended list of functions<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/blue.pri.ee\/ttu\/labs\/pr2en8-dynamic-memory-2\/#Reading_the_file_using_dynamic_memory_allocation\" >Reading the file using dynamic memory allocation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/blue.pri.ee\/ttu\/labs\/pr2en8-dynamic-memory-2\/#Testing\" >Testing<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/blue.pri.ee\/ttu\/labs\/pr2en8-dynamic-memory-2\/#Extra_task_1_W08-2_Optimal_algorithms_for_allocation\" >Extra task 1 [W08-2]: Optimal algorithms for allocation<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/blue.pri.ee\/ttu\/labs\/pr2en8-dynamic-memory-2\/#Requirements-2\" >Requirements<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/blue.pri.ee\/ttu\/labs\/pr2en8-dynamic-memory-2\/#Extra_task_2_W08-3_wrapper_struct\" >Extra task 2 [W08-3]: wrapper struct<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/blue.pri.ee\/ttu\/labs\/pr2en8-dynamic-memory-2\/#Requirements-3\" >Requirements<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/blue.pri.ee\/ttu\/labs\/pr2en8-dynamic-memory-2\/#After_this_class_you_should\" >After this class, you should<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/blue.pri.ee\/ttu\/labs\/pr2en8-dynamic-memory-2\/#Additional_materials\" >Additional materials<\/a><\/li><\/ul><\/nav><\/div>\n<h3><span class=\"ez-toc-section\" id=\"Lab_materials\"><\/span>Lab materials<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li>Slides: <a href=\"https:\/\/blue.pri.ee\/ttu\/files\/iax0584\/slaidid-en\/08_dynamic_memory_management_2.pdf\"><strong>Dynamic memory allocation 2<\/strong><\/a><\/li>\n<li>Additional example: <strong><a href=\"https:\/\/blue.pri.ee\/ttu\/programming-ii\/code-samples\/struct_wrapper_dynamic\/\">wrapper-struct for dynamic array<\/a><\/strong><\/li>\n<\/ul>\n<h3><span class=\"ez-toc-section\" id=\"Lab_tasks\"><\/span>Lab tasks<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>This lab has one task that is extended by two extra tasks<\/p>\n<h4><span class=\"ez-toc-section\" id=\"Lab_task_W08-1_Reading_a_file_dynamically\"><\/span><span style=\"font-size: 20px; font-weight: bold;\">Lab task [W08-1]: Reading a file dynamically<\/span><span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>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.<\/p>\n<h5><span class=\"ez-toc-section\" id=\"Data_file\"><\/span>Data file<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Data file structure for the task: <span class=\"lang:c highlight:0 decode:true crayon-inline\">&lt;index&gt; &lt;last name&gt; &lt;first name&gt; &lt;curriculum code&gt; &lt;points&gt;<\/span><\/p>\n<ul>\n<li>Index (integer)<\/li>\n<li>First and last name &#8211; strings with varying length<\/li>\n<li>Curriculum code &#8211; string with exactly 4 characters<\/li>\n<li>Points &#8211; floating point value from 10.0 to 30.0 with a precision of 0.1.<\/li>\n<\/ul>\n<p>You can use the data file generator from last week for this. To test, we&#8217;ve also provided files so you can compare your output.<\/p>\n<p>Download data files here that we used in the <strong><a href=\"#Testing\">testing<\/a> <\/strong>part.: <strong><a href=\"https:\/\/blue.pri.ee\/ttu\/files\/iax0584\/andmefailid\/8_scholarship_data.zip\">https:\/\/blue.pri.ee\/ttu\/files\/iax0584\/andmefailid\/8_scholarship_data.zip<\/a><\/strong><\/p>\n<h5><span class=\"ez-toc-section\" id=\"Requirements\"><\/span>Requirements<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<ul>\n<li>Read an unknown length data file into memory\n<ul>\n<li>Use <span class=\"lang:c highlight:0 decode:true crayon-inline \">realloc()<\/span>\u00a0 to read the data, expanding your memory as you are reading the file<\/li>\n<li>Store the data into a dynamically created structure array<\/li>\n<li>Once the reading is finished, you allocated memory size must match the exactly to how many were read from the file<\/li>\n<li>You can only read the file once (repeat reading is forbidden, this includes just checking for newline count!)<\/li>\n<li>The length of the file can change\u00a0 &#8211; the exact length is determined during reading.<\/li>\n<\/ul>\n<\/li>\n<li>All variable length strings must be stored in memory exactly (using dynamic memory allocation).\n<ul>\n<li>During reading, use a static buffer and then use dynamic memory to store it into the struct.<\/li>\n<\/ul>\n<\/li>\n<li>The file contains students competing for a scholarship. Scholarships are given for 7 best students (highest points) of the following curriculums: IACB, EARB, MVEB<\/li>\n<li>Print the list of students who will receive the scholarship and also print the number of students who got it from each curriculum.<\/li>\n<li>Make sure there are no memory leaks!<\/li>\n<\/ul>\n<h5><span class=\"ez-toc-section\" id=\"Data_structure_for_the_task\"><\/span>Data structure for the task<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>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:<\/p>\n<pre class=\"toolbar:2 lang:c decode:true\">typedef struct\r\n{\r\n    int index;\r\n    char *fName;\r\n    char *lName;\r\n    char curriculum[LEN_CURRICULUM + 1];\r\n    float points;\r\n} Person;<\/pre>\n<p>Note:<\/p>\n<ul>\n<li>You can alter the naming to your liking.<\/li>\n<li>The <span class=\"lang:c highlight:0 decode:true crayon-inline \">fName<\/span>\u00a0 and <span class=\"lang:c highlight:0 decode:true crayon-inline \">lName<\/span>\u00a0 are now pointers that need dynamic memory allocation due to the length being variable from person to person.<\/li>\n<li>String for the curriculum code is static because the length never changes &#8211; using dynamic memory here would be wasteful (slower and more complex).<\/li>\n<li>Single variables such as index and points remain static because again, using dynamic for those members would be making the program purposefully slower and more complex.<\/li>\n<\/ul>\n<h5><span class=\"ez-toc-section\" id=\"Recommended_list_of_functions\"><\/span>Recommended list of functions<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>NB! The actual form the functions take depends on how you tackle the task.<\/p>\n<p><strong>At minimum<\/strong>, you need three functions:<\/p>\n<ul>\n<li>Reading the data (<strong>check the next subheading<\/strong>).<\/li>\n<li>Printing the results.\n<pre class=\"toolbar:2 lang:c decode:true\">void PrintScholarships(Person *pStudents, int n); \/\/ Good for base task\r\nvoid PrintScholarships(StudentWrapper stdWrapper); \/\/ Good for extra task 2<\/pre>\n<\/li>\n<li>Freeing the memory.\n<pre class=\"toolbar:2 lang:c decode:true\">void FreeStudentData(Person *pStudents, int n); \/\/ Good for base task\r\nvoid FreeStudentData(Person **ppStudents, int n); \/\/ Good for base task using defensive programming\r\nvoid FreeStudentData(StudentWrapper stdWrapper); \/\/ Good for extra task 2<\/pre>\n<\/li>\n<\/ul>\n<p><b>Recommended <\/b>functions to make your life easier<\/p>\n<ul>\n<li>qsort compare function\n<pre class=\"toolbar:2 lang:c decode:true\">int ComparPersonByPoints(const void *a, const void *b);<\/pre>\n<\/li>\n<li>Printing the data of a single student (useful for printing the students who get the scholarship).\n<pre class=\"toolbar:2 lang:c decode:true\">void PrintStudent(Student *s);<\/pre>\n<\/li>\n<li>For defensive programming, use the function shown on the slides\n<pre class=\"toolbar:2 lang:c decode:true\">void FreeMemory(void **p);<\/pre>\n<\/li>\n<\/ul>\n<p>To make sure you read the file correctly, you might want to have a function that just prints everyone&#8217;s data. This is however not a part of the task.<\/p>\n<h5><span class=\"ez-toc-section\" id=\"Reading_the_file_using_dynamic_memory_allocation\"><\/span>Reading the file using dynamic memory allocation<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>From now, the reading function takes a new form. We need to get 2 values from the reading function &#8211; memory location of the array and number of lines read from the file. I&#8217;m proposing a three variants for this\u00a0 function. Choose the one that works for you the best.<\/p>\n<p><strong>Variant 1:<\/strong> Most similar to the previously introduced reading function. It returns the line count and uses a double pointer for for the array.<\/p>\n<p><strong>Variant 2:<\/strong>\u00a0 By returning the array pointer and passing the line count as a pointer, we can avoid the use of a double pointer.<\/p>\n<p><strong>Variant 3:<\/strong> This one uses pointers for both the array and the line count. This allows us to return the status of the function (did it succeed or failed and potentially how it failed).\u00a0 This is also the most similar to the natural style of C functions &#8211; many of them return if the function succeeded or not.<\/p>\n<p>Note, that using a wrapper struct (extra task 2) is also effective on cleaning up the parameter list.<\/p>\n<div class=\"su-tabs su-tabs-style-default su-tabs-mobile-stack\" data-active=\"1\" data-scroll-offset=\"0\" data-anchor-in-url=\"yes\"><div class=\"su-tabs-nav\"><span class=\"\" data-url=\"\" data-target=\"blank\" tabindex=\"0\" role=\"button\">Variant 1<\/span><span class=\"\" data-url=\"\" data-target=\"blank\" tabindex=\"0\" role=\"button\">Variant 2<\/span><span class=\"\" data-url=\"\" data-target=\"blank\" tabindex=\"0\" role=\"button\">Variant 3<\/span><\/div><div class=\"su-tabs-panes\"><div class=\"su-tabs-pane su-u-clearfix su-u-trim\" data-title=\"Variant 1\">\n<pre class=\"lang:c decode:true\">\/**\r\n * Description:   Reads data from a file. During reading, a dynamic\r\n *                struct array will be created and expanded using realloc()\r\n * Parameters:    ppStudentData - Stores the location of the allocated array\r\n *                fileName - name of the input file to read\r\n * Return:        Number of lines read from the file\r\n *\/\r\nint ReadData(Person **ppStudentData, char *fileName)\r\n{\r\n    \/\/ Current line counter\r\n    int count = 0;\r\n\r\n    \/\/ Main pointer for the allocated array\r\n    Person *pData = NULL;\r\n\r\n    \/\/ Declare temporary buffers for reading (all variables you intend to read!)\r\n\r\n\r\n    \/\/ Read a record at a time in a loop into buffer(s)\r\n    while ()\r\n    {\r\n        \/\/ Rellocate memory to fit the latest line, using a temporary variable\r\n        Person *pTemp = realloc(pData, \/* Calculate number of bytes required *\/);\r\n\r\n        \/\/ Check allocation was successful\r\n        if (pTemp == NULL)\r\n        {\r\n            \/* Write error behavior here *\/\r\n        }\r\n\r\n        \/\/ Allocation success, make sure both pointers point at memory\r\n        pData = pTemp;\r\n\r\n        \/\/ 1. Allocate all dynamic buffers (strings in this task)\r\n        \/\/ 2. Copy the data from buffers to struct array\r\n\r\n\r\n        \/\/ Increment number of records successfully read\r\n        count++;\r\n    }\r\n\r\n\r\n    \/\/ Store the allocated array trough the double pointer\r\n    *ppStudentData = pData;\r\n\r\n    \/\/ Return the number of lines read\r\n    return count;\r\n}\r\n<\/pre>\n<\/div>\n<div class=\"su-tabs-pane su-u-clearfix su-u-trim\" data-title=\"Variant 2\">\n<pre class=\"lang:c decode:true\">\/**\r\n * Description:   Reads data from a file. During this, a dynamic\r\n *                struct array will be created and expanded using realloc()\r\n * Parameters:    pLineCount - pointer to store the read line count\r\n *                fileName - name of the input file to read\r\n * Return:        Pointer to the allocated data array\r\n *\/\r\nPerson * ReadData(int *pLineCount, char *fileName)\r\n{\r\n    \/\/ Current line counter\r\n    int count = 0;\r\n\r\n    \/\/ Main pointer for the allocated array\r\n    Person *pData = NULL;\r\n\r\n    \/\/ Declare temporary buffers for reading (all variables you intend to read!)\r\n\r\n\r\n    \/\/ Read a record at a time in a loop into buffer(s)\r\n    while ()\r\n    {\r\n        \/\/ Rellocate memory to fit the latest line, using a temporary variable\r\n        Person *pTemp = realloc(pData, \/* Calculate number of bytes required *\/);\r\n\r\n        \/\/ Check allocation was successful\r\n        if (pTemp == NULL)\r\n        {\r\n            \/* Write error behavior here *\/\r\n        }\r\n\r\n        \/\/ Allocation success, make sure both pointers point at memory\r\n        pData = pTemp;\r\n\r\n        \/\/ 1. Allocate all dynamic buffers (strings in this task)\r\n        \/\/ 2. Copy the data from buffers to struct array\r\n\r\n\r\n        \/\/ Increment number of records successfully read\r\n        count++;\r\n    }\r\n\r\n\r\n    \/\/ Store the number of lines trough the pointer\r\n    *pLineCount = count;\r\n\r\n    \/\/ Return the pointer to the data\r\n    return pData;\r\n}\r\n<\/pre>\n<\/div>\n<div class=\"su-tabs-pane su-u-clearfix su-u-trim\" data-title=\"Variant 3\">\n<pre class=\"lang:c decode:true \">\/**\r\n * Description:   Read data from a file. During this, a dynamic\r\n *                struct array will be created and expanded using realloc()\r\n * Parameters:    ppStudentData - Stores the location of the allocated array\r\n *                pLineCount - pointer to store the read line count\r\n *                fileName - name of the input file to read\r\n * Return:        0 if data is read successfully\r\n *                1 if error is encountered\r\n *\/\r\nint ReadData(Person **ppStudentData, int *pLineCount, char *fileName)\r\n{\r\n    \/\/ Current line counter\r\n    int count = 0;\r\n\r\n    \/\/ Main pointer for the allocated array\r\n    Person *pData = NULL;\r\n\r\n    \/\/ Declare temporary buffers for reading (all variables you intend to read!)\r\n\r\n\r\n    \/\/ Read a record at a time in a loop into buffer(s)\r\n    \/\/ Note: if you encounter an error, return a NON-ZERO value!\r\n    while ()\r\n    {\r\n        \/\/ Rellocate memory to fit the latest line, using a temporary variable\r\n        Person *pTemp = realloc(pData, \/* Calculate number of bytes required *\/);\r\n\r\n        \/\/ Check allocation was successful\r\n        if (pTemp == NULL)\r\n        {\r\n            \/* Write error behavior here *\/\r\n        }\r\n\r\n        \/\/ Allocation success, make sure both pointers point at memory\r\n        pData = pTemp;\r\n\r\n        \/\/ 1. Allocate all dynamic buffers (strings in this task)\r\n        \/\/ 2. Copy the data from buffers to struct array\r\n\r\n\r\n        \/\/ Increment number of records successfully read\r\n        count++;\r\n    }\r\n\r\n    \/\/ Store the allocated array trough the double pointer\r\n    *ppStudentData = pData;\r\n\r\n    \/\/ Store the number of lines trough the pointer\r\n    *pLineCount= count;\r\n\r\n    \/\/ Everything OK\r\n    return 0;\r\n}\r\n<\/pre>\n<\/div><\/div><\/div>\n<h5><span class=\"ez-toc-section\" id=\"Testing\"><\/span>Testing<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>In the first file, we&#8217;re using the longer data file where all scholarships got assigned. Notice the heap summary!<\/p>\n<pre class=\"theme:cisco-router toolbar:2 nums:false wrap:true lang:c highlight:0 decode:true \">risto@risto-lt3-tux:~\/Nextcloud\/work\/ttu\/teaching\/_generic\/prog2\/lab\/wk8_scholarships$ valgrind .\/scholarships v1.txt\r\n==14380== Memcheck, a memory error detector\r\n==14380== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.\r\n==14380== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info\r\n==14380== Command: .\/scholarships v1.txt\r\n==14380==\r\nInd   fName        lName        Code   Points\r\n 13   Laivi        Kaasik       IACB    30.0\r\n 75   Julia        Saal         MVEB    30.0\r\n  3   Kerttu       Allik        MVEB    29.8\r\n 25   Ingrid       Kukk         MVEB    29.8\r\n  5   Valdo        Heinsoo      IACB    29.7\r\n 77   Jaan         Saar         IACB    29.7\r\n  9   Kristi       Hunt         IACB    29.5\r\n 20   Doris        Vares        IACB    29.5\r\n 76   Annika       Saar         EARB    29.5\r\n 36   Veljo        Lepp         MVEB    29.4\r\n 10   Hendrik      Ivanov       IACB    29.1\r\n 38   Monika       Leppik       MVEB    29.1\r\n 22   Anna         Kruuse       MVEB    29.0\r\n 51   Mare         Paas         IACB    28.2\r\n 80   Rainer       Sepp         EARB    27.8\r\n 59   Kristiina    Petrov       MVEB    27.6\r\n 45   Tatjana      Orav         EARB    26.7\r\n 74   Anneli       Saal         EARB    26.3\r\n 69   Tiina        Raud         EARB    25.1\r\n  8   Anna         Herkel       EARB    23.0\r\n 65   Denis        Purga        EARB    21.7\r\n\r\n\r\nEARB: 7 \/ 7 scholarsips assigned\r\nIACB: 7 \/ 7 scholarsips assigned\r\nMVEB: 7 \/ 7 scholarsips assigned\r\n==14380==\r\n==14380== HEAP SUMMARY:\r\n==14380==     in use at exit: 0 bytes in 0 blocks\r\n==14380==   total heap usage: 175 allocs, 175 frees, 20,396 bytes allocated\r\n==14380==\r\n==14380== All heap blocks were freed -- no leaks are possible\r\n==14380==\r\n==14380== For lists of detected and suppressed errors, rerun with: -s\r\n==14380== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)<\/pre>\n<p>In the second example, I&#8217;m using the shorter data file.<\/p>\n<pre class=\"theme:cisco-router toolbar:2 nums:false wrap:true lang:c highlight:0 decode:true\">risto@risto-lt3-tux:~\/Nextcloud\/work\/ttu\/teaching\/_generic\/prog2\/lab\/wk8_scholarships$ valgrind .\/scholarships v2.txt\r\n==14397== Memcheck, a memory error detector\r\n==14397== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.\r\n==14397== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info\r\n==14397== Command: .\/scholarships v2.txt\r\n==14397==\r\nInd   fName        lName        Code   Points\r\n  5   Laivi        Kaasik       IACB    30.0\r\n  0   Kerttu       Allik        MVEB    29.8\r\n  3   Hendrik      Ivanov       IACB    29.1\r\n  6   Kristi       Kalda        IACB    27.0\r\n  9   Jevgeni      Kuusk        MVEB    25.0\r\n  2   Anna         Herkel       EARB    23.0\r\n 11   Tiina        Laas         IACB    22.4\r\n  4   Milvi        Jakobson     IACB    19.5\r\n  7   Mati         Kruuse       IACB    17.3\r\n 10   Liis         Kuusk        MVEB    17.2\r\n  1   Sirje        Helme        EARB    12.9\r\n  8   Mihkel       Kruuse       MVEB    10.6\r\n\r\n\r\nEARB: 2 \/ 7 scholarsips assigned\r\nIACB: 6 \/ 7 scholarsips assigned\r\nMVEB: 4 \/ 7 scholarsips assigned\r\n==14397==\r\n==14397== HEAP SUMMARY:\r\n==14397==     in use at exit: 0 bytes in 0 blocks\r\n==14397==   total heap usage: 29 allocs, 29 frees, 6,947 bytes allocated\r\n==14397==\r\n==14397== All heap blocks were freed -- no leaks are possible\r\n==14397==\r\n==14397== For lists of detected and suppressed errors, rerun with: -s\r\n==14397== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)\r\n<\/pre>\n<h4><span class=\"ez-toc-section\" id=\"Extra_task_1_W08-2_Optimal_algorithms_for_allocation\"><\/span>Extra task 1 [W08-2]: Optimal algorithms for allocation<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>In this task we&#8217;re changing the algorithm how we are allocating memory to a more reasonable one.<\/p>\n<h5><span class=\"ez-toc-section\" id=\"Requirements-2\"><\/span>Requirements<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<ul>\n<li>Change the file reading in a way that you would be using the (n * 2) expansion strategy\n<ul>\n<li>Every time you run out of memory, you reallocate to a 2x higher amount that you have right now.<\/li>\n<\/ul>\n<\/li>\n<li>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).<\/li>\n<\/ul>\n<h4><span class=\"ez-toc-section\" id=\"Extra_task_2_W08-3_wrapper_struct\"><\/span>Extra task 2 [W08-3]: wrapper struct<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>In this task, we&#8217;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.<\/p>\n<h5><span class=\"ez-toc-section\" id=\"Requirements-3\"><\/span>Requirements<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<ul>\n<li>Put your structure array pointer into the other struct (wrapper)<\/li>\n<li>In your wrapper, you should have 3 variables &#8211; pointer to the struct, number of structs allocated, number of structs used<\/li>\n<li>Change your function parameters for the existing functions to use the new wrapper struct<\/li>\n<li>NB! Think through for which functions it is required to pass a pointer to the wrapper where it is unnecessary.<\/li>\n<\/ul>\n<p>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 &#8220;unpack&#8221; those variables when you need to use them. See the following example.<\/p>\n<pre class=\"toolbar:2 lang:c decode:true \">void PrintData(student_wrapper stdWrap)\r\n{\r\n    int len = stdWrap.used;\r\n\r\n    for (int i = 0; i &lt; len; i++)\r\n    {\r\n        student *s = &amp;stdWrap.studentDB[i];\r\n\r\n    }\r\n}<\/pre>\n<h3><span class=\"ez-toc-section\" id=\"After_this_class_you_should\"><\/span>After this class, you should<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li>Know how to use defensive programming to handle memory freeing<\/li>\n<li>Know the definition of a dangling pointer and how to safely handle dangling pointers<\/li>\n<li>be able to to structure your code in order to read files that can be of any length<\/li>\n<li>be able to handle changing the size of a dynamically allocated array<\/li>\n<li>be able to read data into an expanding array using dynamic memory allocation<\/li>\n<li>know all possible ways realloc works<\/li>\n<li>know the difference between (n + 1) and (n * 2) allocation strategies and be able to implemetn at least one of the two<\/li>\n<li>be able to\u00a0 allocate memory to members of structures<\/li>\n<li>Know all the steps strdup() does in the background and be able to use it<\/li>\n<\/ul>\n<h3><span class=\"ez-toc-section\" id=\"Additional_materials\"><\/span>Additional materials<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li>cppreference: Realloc documentation<br \/>\n<strong><a href=\"https:\/\/en.cppreference.com\/w\/c\/memory\/realloc\">https:\/\/en.cppreference.com\/w\/c\/memory\/realloc<\/a><\/strong><\/li>\n<li>Beej&#8217;s guide: Changing allocated size<br \/>\n<a href=\"https:\/\/beej.us\/guide\/bgc\/html\/split\/manual-memory-allocation.html#changing-allocated-size-with-realloc\"><strong>https:\/\/beej.us\/guide\/bgc\/html\/split\/manual-memory-allocation.html#changing-allocated-size-with-realloc<\/strong><\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Lab materials Slides: Dynamic memory allocation 2 Additional example: wrapper-struct for dynamic array Lab tasks This lab has one task that is extended by two extra tasks Lab task [W08-1]: 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 &hellip; <a href=\"https:\/\/blue.pri.ee\/ttu\/labs\/pr2en8-dynamic-memory-2\/\" class=\"more-link\">Loe edasi <span class=\"screen-reader-text\">PR2EN8: Dynamic memory 2<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[75,105],"tags":[],"class_list":["post-8357","post","type-post","status-publish","format-standard","hentry","category-labs","category-pr2_en"],"_links":{"self":[{"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/posts\/8357","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/comments?post=8357"}],"version-history":[{"count":19,"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/posts\/8357\/revisions"}],"predecessor-version":[{"id":11304,"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/posts\/8357\/revisions\/11304"}],"wp:attachment":[{"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/media?parent=8357"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/categories?post=8357"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/tags?post=8357"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}