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.