To treat a chunk of memory as a file, it must be “opened” and a handle returned for future file reference and interaction. Likewise, the memory-file must be “closed” when you no longer need it. To accomplish these tasks, I’ve crafted the mem_open() and mem_close() functions.
Both of these functions use a mem_file structure, introduced in last week’s Lesson. The mem_open() function swallows a string to represent the memory-file name. It returns a pointer to a mem_file structure upon success, NULL
otherwise.
The mem_close() function requires a mem_file structure pointer as an argument. It has no return value.
The following code uses these functions to create a memory-file then close the memory file.
2023_09_02-Lesson-a.c
#include <stdio.h> #include <stdlib.h> #include <time.h> #define DEFAULT_SIZE 2048 struct mem_file { void *address; char *name; int size; int offset; char *timestamp; }; /* create a memory file input: filename string output: pointer to memory file structure, NULL on failure */ struct mem_file *mem_open(char *fn) { struct mem_file *mem_new; time_t now; /* error checking */ if( fn==NULL ) return(NULL); /* allocate storage for memory file structure */ mem_new = malloc( sizeof(struct mem_file) ); if( mem_new==NULL ) return(NULL); /* populate structure */ mem_new->address = malloc( DEFAULT_SIZE ); if( mem_new->address==NULL ) return(NULL); mem_new->name=fn; /* set memory file name */ mem_new->size = 0; /* set size */ mem_new->offset = 0; /* offset/file pointer */ /* create timestemp */ time(&now); mem_new->timestamp = ctime(&now); return(mem_new); } /* close memory file, free memory input: mem_file structure of an open memory file */ void mem_close(struct mem_file *m) { free(m->address); free(m); } /* test the memory file functions */ int main() { static char name1[] = "memory file"; struct mem_file *mfp1; mfp1 = mem_open(name1); if( mfp1==NULL ) { fprintf(stderr,"Unable to create %s\n",name1); exit(1); } printf("Memory file '%s' created\n",name1); printf("Timestamp = %s\n",mfp1->timestamp); printf("Press Enter: "); getchar(); mem_close(mfp1); printf("Memory file '%s' closed\n",name1); return(0); }
The mem_open() function immediately checks for an empty string and returns NULL when no string is specified:
if( fn==NULL )
return(NULL);
Next, memory is allocated for the mem_file structure. This step takes place first and, upon success, memory is then allocated for the memory-file itself based upon the value of DEFAULT_SIZE
. If either allocation fails, NULL
is returned.
The remainder of the mem_open() function assigns values to the members: the filename, the memory_file size, offset, and timestamp string. The mem_file structure’s address is then returned.
The mem_close() function contains only two statements. The first frees the memory-file’s allocated storage, saved in member address. The second statement frees the mem_file structure itself.
The main() function creates a memory-file. It outputs the memory-file’s timestamp, waits for a key press, then closes the memory-file. Here’s sample output:
Memory file 'memory file' created
Timestamp = Sat Sep 2 10:02:13 2023
Press Enter:
Memory file 'memory file' closed
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’t contaminate the first. This code is available on GitHub, and here is its output:
Memory file 'memory file' created
Timestamp = Sat Aug 19 10:05:10 2023
Press Enter:
Memory file 'memory file two' created
Timestamp = Sat Aug 19 10:05:12 2023
Memory file 'memory file' closed
Memory file 'memory file two' closed
The Press Enter
prompt helps to ensure that both memory-files don’t have identical timestamps.
Unlike media files, when these memory-files are closed, they’re gone for good. Memory-files don’t linger in memory ready to be re-opened. For that to happen, I’d need to implement a memory-file file system. That’s too much work! My approach here is to mimic file access by using a chunk of memory.
Next week I continue this exploration with functions to write to and read from the memory-file.