{"id":6013,"date":"2023-09-02T00:01:23","date_gmt":"2023-09-02T07:01:23","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=6013"},"modified":"2023-09-09T09:09:27","modified_gmt":"2023-09-09T16:09:27","slug":"opening-and-closing-memory-files","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=6013","title":{"rendered":"Opening and Closing Memory-Files"},"content":{"rendered":"<p>To treat a chunk of memory as a file, it must be &#8220;opened&#8221; and a handle returned for future file reference and interaction. Likewise, the memory-file must be &#8220;closed&#8221; when you no longer need it. To accomplish these tasks, I&#8217;ve crafted the <em>mem_open()<\/em> and <em>mem_close()<\/em> functions.<br \/>\n<!--more--><br \/>\nBoth of these functions use a <em>mem_file<\/em> structure, introduced in <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5982\">last week&#8217;s Lesson<\/a>. The <em>mem_open()<\/em> function swallows a string to represent the memory-file name. It returns a pointer to a <em>mem_file<\/em> structure upon success, <code>NULL<\/code> otherwise.<\/p>\n<p>The <em>mem_close()<\/em> function requires a <em>mem_file<\/em> structure pointer as an argument. It has no return value.<\/p>\n<p>The following code uses these functions to create a memory-file then close the memory file.<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2023_09_02-Lesson-a.c\" rel=\"noopener\" target=\"_blank\">2023_09_02-Lesson-a.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;time.h&gt;\r\n\r\n#define DEFAULT_SIZE 2048\r\n\r\nstruct mem_file {\r\n    void *address;\r\n    char *name;\r\n    int size;\r\n    int offset;\r\n    char *timestamp;\r\n};\r\n\r\n<span class=\"comments\">\/* create a memory file\r\n   input: filename string\r\n   output: pointer to memory file structure,\r\n           NULL on failure\r\n *\/<\/span>\r\nstruct mem_file *mem_open(char *fn)\r\n{\r\n    struct mem_file *mem_new;\r\n    time_t now;\r\n\r\n    <span class=\"comments\">\/* error checking *\/<\/span>\r\n    if( fn==NULL )\r\n        return(NULL);\r\n\r\n    <span class=\"comments\">\/* allocate storage for memory file structure *\/<\/span>\r\n    mem_new = malloc( sizeof(struct mem_file) );\r\n    if( mem_new==NULL )\r\n        return(NULL);\r\n\r\n    <span class=\"comments\">\/* populate structure *\/<\/span>\r\n    mem_new-&gt;address = malloc( DEFAULT_SIZE );\r\n    if( mem_new-&gt;address==NULL )\r\n        return(NULL);\r\n    mem_new-&gt;name=fn;        <span class=\"comments\">\/* set memory file name *\/<\/span>\r\n    mem_new-&gt;size = 0;        <span class=\"comments\">\/* set size *\/<\/span>\r\n    mem_new-&gt;offset = 0;    <span class=\"comments\">\/* offset\/file pointer *\/<\/span>\r\n        <span class=\"comments\">\/* create timestemp *\/<\/span>\r\n    time(&amp;now);\r\n    mem_new-&gt;timestamp = ctime(&amp;now);\r\n\r\n    return(mem_new);\r\n}\r\n\r\n<span class=\"comments\">\/*\r\n   close memory file, free memory\r\n   input: mem_file structure of an open\r\n           memory file\r\n *\/<\/span>\r\nvoid mem_close(struct mem_file *m)\r\n{\r\n    free(m-&gt;address);\r\n    free(m);\r\n}\r\n\r\n<span class=\"comments\">\/* test the memory file functions *\/<\/span>\r\nint main()\r\n{\r\n    static char name1[] = \"memory file\";\r\n    struct mem_file *mfp1;\r\n\r\n    mfp1 = mem_open(name1);\r\n    if( mfp1==NULL )\r\n    {\r\n        fprintf(stderr,\"Unable to create %s\\n\",name1);\r\n        exit(1);\r\n    }\r\n\r\n    printf(\"Memory file '%s' created\\n\",name1);\r\n    printf(\"Timestamp = %s\\n\",mfp1-&gt;timestamp);\r\n\r\n    printf(\"Press Enter: \");\r\n    getchar();\r\n\r\n    mem_close(mfp1);\r\n    printf(\"Memory file '%s' closed\\n\",name1);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>mem_open()<\/em> function immediately checks for an empty string and returns NULL when no string is specified:<\/p>\n<p><code>if( fn==NULL )<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;return(NULL);<\/code><\/p>\n<p>Next, memory is allocated for the <em>mem_file<\/em> structure. This step takes place first and, upon success, memory is then allocated for the memory-file itself based upon the value of <code>DEFAULT_SIZE<\/code>. If either allocation fails, <code>NULL<\/code> is returned.<\/p>\n<p>The remainder of the <em>mem_open()<\/em> function assigns values to the members: the filename, the memory_file size, offset, and timestamp string. The <em>mem_file<\/em> structure&#8217;s address is then returned.<\/p>\n<p>The <em>mem_close()<\/em> function contains only two statements. The first frees the memory-file&#8217;s allocated storage, saved in member <em>address<\/em>. The second statement frees the <em>mem_file<\/em> structure itself.<\/p>\n<p>The <em>main()<\/em> function creates a memory-file. It outputs the memory-file&#8217;s timestamp, waits for a key press, then closes the memory-file. Here&#8217;s sample output:<\/p>\n<p><code>Memory file 'memory file' created<br \/>\nTimestamp = Sat Sep&nbsp;&nbsp;2 10:02:13 2023<\/p>\n<p>Press Enter:<br \/>\nMemory file 'memory file' closed<\/code><\/p>\n<p>Because these functions worked so well, I decided to modify the code to open a second memory-file. I wanted to ensure that a second memory-file wouldn&#8217;t contaminate the first. This code is <a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2023_09_02-Lesson-b.c\" rel=\"noopener\" target=\"_blank\">available on GitHub<\/a>, and here is its output:<\/p>\n<p><code>Memory file 'memory file' created<br \/>\nTimestamp = Sat Aug 19 10:05:10 2023<\/p>\n<p>Press Enter:<br \/>\nMemory file 'memory file two' created<br \/>\nTimestamp = Sat Aug 19 10:05:12 2023<\/p>\n<p>Memory file 'memory file' closed<br \/>\nMemory file 'memory file two' closed<\/code><\/p>\n<p>The <code>Press Enter<\/code> prompt helps to ensure that both memory-files don&#8217;t have identical timestamps.<\/p>\n<p>Unlike media files, when these memory-files are closed, they&#8217;re gone for good. Memory-files don&#8217;t linger in memory ready to be re-opened. For that to happen, I&#8217;d need to implement a memory-file file system. That&#8217;s too much work! My approach here is to mimic file access by using a chunk of memory.<\/p>\n<p><a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6022\">Next week<\/a> I continue this exploration with functions to write to and read from the memory-file.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>To treat a chunk of memory as a file, you must have memory-file open and close functions. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6013\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-6013","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6013","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6013"}],"version-history":[{"count":5,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6013\/revisions"}],"predecessor-version":[{"id":6034,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6013\/revisions\/6034"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6013"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6013"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6013"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}