{"id":3736,"date":"2018-02-28T15:24:08","date_gmt":"2018-02-28T13:24:08","guid":{"rendered":"https:\/\/blue.pri.ee\/ttu\/?page_id=3736"},"modified":"2026-06-01T12:59:52","modified_gmt":"2026-06-01T10:59:52","slug":"struct_wrapper_dynamic","status":"publish","type":"page","link":"https:\/\/blue.pri.ee\/ttu\/programmeerimine-ii\/koodinaited\/struct_wrapper_dynamic\/","title":{"rendered":"\u00dcmbris-struktuur d\u00fcnaamilisele massiivile"},"content":{"rendered":"<p>J\u00e4rgnev n\u00e4ide demonstreerib \u00fcmbrisstruktuuri (<em>wrapper<\/em>) kasutamist d\u00fcnaamilisele massiivile. \u00dcmbrise eesm\u00e4rk on lihtsustada massiivi ligip\u00e4\u00e4su ning suuruse haldamist &#8211; st kus andmed paiknevad, palju liikmeid massiivis on ning mitme liikme jaoks m\u00e4lu parasjagu eksisteerib.<\/p>\n<p>Testimiseks on lisatud k\u00e4surea sisend (<span class=\"lang:c highlight:0 decode:true  crayon-inline \">stdin<\/span> ) koos ettem\u00e4\u00e4ratud t\u00f6\u00f6vooga.<\/p>\n<ol>\n<li>Luuakse massiiv, mis mahutab kaks kirjet<\/li>\n<li>Massiivi lisatakse kaks kirjet<\/li>\n<li>Proovitakse lisada veel kolm kirjet<\/li>\n<\/ol>\n<p>Kolmanda sammu tulemus s\u00f5ltub <span class=\"lang:c highlight:0 decode:true  crayon-inline \">EXPANDABLE<\/span>\u00a0 makro v\u00e4\u00e4rtusest (1 v\u00f5i 0).<\/p>\n<p>Etteantud sisendiga faili saab kasutada koos voo suunamisega: <span class=\"lang:sh decode:true crayon-inline \">.\/programm &lt; testandmed.txt<\/span> .<\/p>\n<pre class=\"toolbar:1 lang:default decode:true\">2\r\n2\r\n0114 Rasmus Aare 38101012210 9.20\r\n0115 Tarmo Waldorf 38909091120 14.20\r\n3\r\n0116 Jane Kask 48511113320 12.20\r\n0117 Aare Kallas 38412124330 7.45\r\n0118 Alexandra Sepp 49105040334 15.00<\/pre>\n<p>Programm koosneb p\u00e4ise- ja koodifailist. Koodifail sisaldab eelnevalt viidatud <span class=\"lang:c highlight:0 decode:true  crayon-inline \">EXPANDABLE<\/span>\u00a0 makrot. Kui makro v\u00e4\u00e4rtus on 1, laiendatakse m\u00e4lu kasutades realloc() funktsiooni. Kui makro on v\u00e4\u00e4rtusel 0, fikseeritakse massiivi suurus esimese kasutaja sisendiga.<\/p>\n<p>Laiendamisel kasutatakse p\u00f5him\u00f5tet, et iga kord suurendatakse m\u00e4lumahtu 2x olemasolevast.<\/p>\n<pre class=\"toolbar:1 lang:c decode:true\" title=\"wrapper.h\">\/**\r\n * File:        wrapper_struct.h\r\n * Author:      Risto Heinsar\r\n * Created:     28.02.2018\r\n * Edited:      01.06.2026\r\n *\r\n * Description: Header containing the Employee struct definition and the wrapper\r\n *              used to manage memory for Employee array\r\n *\/\r\n\r\n#ifndef WRAPPER_STRUCT_H\r\n#define WRAPPER_STRUCT_H\r\n\r\n#include &lt;stdio.h&gt; \/\/ Required for size_t\r\n\r\n#define EID_LEN 12\r\n#define MAX_NAME 256\r\n\r\ntypedef struct\r\n{\r\n    int code;\r\n    char fName[MAX_NAME];\r\n    char lName[MAX_NAME];\r\n    char eID[EID_LEN];\r\n    float wagePerHour;\r\n} Employee;\r\n\r\ntypedef struct\r\n{\r\n    Employee *db;\r\n    size_t limit;\r\n    size_t used;\r\n} EmployeeList;\r\n\r\nvoid AllocateList(EmployeeList *wf);\r\nvoid InsertMembers(EmployeeList *wf);\r\nvoid InsertMembersWithExpandability(EmployeeList *wf);\r\nvoid PrintMembers(EmployeeList wf);\r\nEmployee CreateMember();\r\n\r\n#endif \/\/ WRAPPER_STRUCT_H\r\n<\/pre>\n<pre class=\"toolbar:1 lang:c decode:true\" title=\"wrapper_struct_dynamic.c\">\/**\r\n * File:        wrapper_struct.c\r\n * Author:      Risto Heinsar\r\n * Created:     28.02.2018\r\n * Edited:      01.06.2026\r\n *\r\n * Description: The following example demonstrates two techniques regarding\r\n *              dynamic memory allocation.\r\n * \r\n *              First, a wrapper struct for dynamic array is demonstrated.\r\n *              This helps to keep track of the array size cleanly.\r\n * \r\n *              Second, expanding dynamic memory using (n * 2) strategy is\r\n *              shown, that will greatly improve allocation speed.\r\n *\/\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include \"wrapper_struct.h\"\r\n\r\n\/\/  Use 0 for non-expandable list, \r\n\/\/      1 for expandable using realloc.\r\n#define EXPANDABLE 1\r\n\r\nint main(void)\r\n{\r\n    EmployeeList workForce = {.db    = NULL, \r\n                              .limit = 0, \r\n                              .used  = 0};\r\n    AllocateList(&amp;workForce);\r\n\r\n    if (EXPANDABLE)\r\n    {\r\n        InsertMembersWithExpandability(&amp;workForce);\r\n        InsertMembersWithExpandability(&amp;workForce);\r\n    }\r\n    else\r\n    {\r\n        InsertMembers(&amp;workForce);\r\n        InsertMembers(&amp;workForce);\r\n    }\r\n\r\n    PrintMembers(workForce);\r\n    \r\n    free(workForce.db);\r\n    return 0;\r\n}\r\n\r\n\/**\r\n * Allocate an initial list, mostly for demonstrative purposes and compatibility\r\n * with both methods of inserting members (fixed and expandable)\r\n *\/\r\nvoid AllocateList(EmployeeList *wf)\r\n{\r\n    unsigned n;\r\n    \r\n    printf(\"For many employees is storage required?\\n\");\r\n    scanf(\"%u\", &amp;n);\r\n    \r\n    wf-&gt;db = calloc(n, sizeof(Employee));\r\n    if (wf-&gt;db == NULL)\r\n    {\r\n        perror(\"Error allocating memory\");\r\n        exit(EXIT_FAILURE);\r\n    }\r\n    \r\n    wf-&gt;limit = n;\r\n}\r\n\r\n\/**\r\n * Insert members to the structure array. This is only capable of adding members\r\n * until the array is full. It will also keep track of how many members have \r\n * been added. The array cannot be expanded using this function.\r\n *\/\r\nvoid InsertMembers(EmployeeList *wf)\r\n{\r\n    size_t n;\r\n    \r\n    printf(\"How many employees to add?\\n\");\r\n    scanf(\"%zu\", &amp;n);\r\n        \r\n    \/\/ Detect if employees array can't fit the requested number of employees\r\n    if (n &gt; wf-&gt;limit - wf-&gt;used)\r\n    {\r\n        fprintf(stderr, \"Error! %zu out of %zu slots are in use.\\n\", wf-&gt;used, \r\n                                                                     wf-&gt;limit);\r\n        fprintf(stderr, \"Storage left for %zu slots\\n\", wf-&gt;limit - wf-&gt;used);\r\n        return;\r\n    }\r\n    \r\n    for (size_t i = 0; i &lt; n; i++)\r\n    {\r\n        printf(\"Adding member %zu out of %zu\\n\", i + 1, n);\r\n        *(wf-&gt;db + wf-&gt;used) = CreateMember();\r\n        wf-&gt;used++;\r\n    }\r\n}\r\n\r\n\r\n\/**\r\n * Insert members to the structure array. This function will try to expand\r\n * the dynamically allocated array if possible. If expanding memory fails, \r\n * the program can be allowed to continue.\r\n *\/\r\nvoid InsertMembersWithExpandability(EmployeeList *wf)\r\n{\r\n    size_t n;\r\n\r\n    printf(\"How many employees to add?\\n\");\r\n    scanf(\"%zu\", &amp;n);\r\n\r\n    size_t i = 0;\r\n    while (i &lt; n)\r\n    {\r\n        \/\/ Detect if array is full and needs expanding\r\n        if (wf-&gt;limit &lt;= wf-&gt;used)\r\n        {\r\n            \/\/ let's make the new limit 2x from what we had\r\n            size_t newLimit = 2 * wf-&gt;limit;\r\n            printf(\"Attempting to expand array from %zu to %zu\\n\", wf-&gt;limit,\r\n                                                                   newLimit);\r\n            \/\/ Expand the array memory block\r\n            Employee *pTemp = realloc(wf-&gt;db, sizeof(Employee) * newLimit);\r\n\r\n            \/\/ Handle allocation failure\r\n            if (pTemp == NULL)\r\n            {\r\n                fprintf(stderr, \"Error: Memory allocation failed!\\n\");\r\n                fprintf(stderr, \"Previously allocated data is safe. \");\r\n                fprintf(stderr, \"Allocation exists for %zu items\\n\", wf-&gt;limit);\r\n                break;\r\n            }\r\n\r\n            \/\/ \"sync\" the pointers and update the limit\r\n            wf-&gt;db = pTemp;\r\n            wf-&gt;limit = newLimit;\r\n            printf(\"Allocation success! New limit is %zu\\n\", wf-&gt;limit);\r\n        }\r\n        \r\n        printf(\"Adding member %zu out of %zu\\n\", i + 1, n);\r\n        *(wf-&gt;db + wf-&gt;used) = CreateMember();\r\n        \r\n        wf-&gt;used++;\r\n        i++;\r\n    }\r\n}\r\n\r\n\r\n\/**\r\n * Creates a new struct member with data from user. The struct will be returned\r\n * so it can be added to the appropriate array later using the preferred method.\r\n *\/\r\nEmployee CreateMember()\r\n{\r\n    Employee newEmployee;\r\n    \r\n    \/* static variables are scope limited, but have global lifetime *\/\r\n    static int employeeCode = 0;\r\n    newEmployee.code = employeeCode++;\r\n    \r\n    printf(\"Enter first name:\\n\");\r\n    scanf(\"%s\", newEmployee.fName);\r\n    printf(\"Enter last name:\\n\");\r\n    scanf(\"%s\", newEmployee.lName);\r\n    printf(\"Enter Estonian identification number:\\n\");\r\n    scanf(\"%s\", newEmployee.eID);\r\n    printf(\"Enter wage per hour:\\n\");\r\n    scanf(\"%f\", &amp;newEmployee.wagePerHour);\r\n    return newEmployee;\r\n}\r\n\r\n\r\n\/**\r\n * Prints the list of members in the struct array\r\n *\/\r\nvoid PrintMembers(EmployeeList wf)\r\n{\r\n    printf(\"%zu out of %zu slots are in use\\n\", wf.used, wf.limit);\r\n    \r\n    if (wf.used &lt;= 0)\r\n    {\r\n        return;\r\n    }\r\n    \r\n    printf(\"%7s %12s %15s %15s %6s\\n\", \"code\", \"eID\", \"fName\", \"lName\", \"wage\");\r\n    for (size_t i = 0; i &lt; wf.used; i++)\r\n    {\r\n        printf(\"%7d %12s %15s %15s %6.2f\\n\", (wf.db + i)-&gt;code,\r\n                                             (wf.db + i)-&gt;eID, \r\n                                             (wf.db + i)-&gt;fName, \r\n                                             (wf.db + i)-&gt;lName, \r\n                                             (wf.db + i)-&gt;wagePerHour);\r\n    }\r\n}<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>J\u00e4rgnev n\u00e4ide demonstreerib \u00fcmbrisstruktuuri (wrapper) kasutamist d\u00fcnaamilisele massiivile. \u00dcmbrise eesm\u00e4rk on lihtsustada massiivi ligip\u00e4\u00e4su ning suuruse haldamist &#8211; st kus andmed paiknevad, palju liikmeid massiivis on ning mitme liikme jaoks m\u00e4lu parasjagu eksisteerib. Testimiseks on lisatud k\u00e4surea sisend (stdin ) koos ettem\u00e4\u00e4ratud t\u00f6\u00f6vooga. Luuakse massiiv, mis mahutab kaks kirjet Massiivi lisatakse kaks kirjet Proovitakse lisada &hellip; <a href=\"https:\/\/blue.pri.ee\/ttu\/programmeerimine-ii\/koodinaited\/struct_wrapper_dynamic\/\" class=\"more-link\">Loe edasi <span class=\"screen-reader-text\">\u00dcmbris-struktuur d\u00fcnaamilisele massiivile<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":684,"menu_order":18,"comment_status":"closed","ping_status":"closed","template":"page-templates\/code-width.php","meta":{"footnotes":""},"class_list":["post-3736","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/pages\/3736","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/types\/page"}],"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=3736"}],"version-history":[{"count":5,"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/pages\/3736\/revisions"}],"predecessor-version":[{"id":11446,"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/pages\/3736\/revisions\/11446"}],"up":[{"embeddable":true,"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/pages\/684"}],"wp:attachment":[{"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/media?parent=3736"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}