logo
down
shadow

Mmap and struct in C


Mmap and struct in C

By : user2950696
Date : November 17 2020, 11:58 AM
wish helps you I would like to read and write structs with mmap in C. , In your code, you have:
code :
int result;
struct map*;  /* mmapped array of structs */
int result;
struct med *map = 0;  /* mmapped array of struct med */
map = (struct*)mmap(0, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
map[i]=&s;
if (m.key == map[i].key)
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

#define FILEPATH "/tmp/mmapped.bin"
#define NUMINTS (1000)
#define FILESIZE (NUMINTS * sizeof(struct med))

struct med
{
    int key;
    char name[25];
    int quant_min;
    int quant;
};

static void print_med(const char *tag, const struct med *med)
{
    printf("%s: %4d: Q(%2d, min %2d): %s\n",
           tag, med->key, med->quant, med->quant_min, med->name);
}

static int med_in_map(const struct med *map, int num_meds, int key)
{
    for (int i = 0; i < num_meds; ++i)
    {
        if (key == map[i].key)
        {
            printf("Med %d already exists.\n", key);
            return 1;
        }
    }
    return 0;
}

static int get_new_key(const struct med *map, int num_meds, int *key)
{
    while (printf("Key of med: ") > 0 && scanf("%d", key) == 1)
    {
        if (med_in_map(map, num_meds, *key) == 0)
            return 0;
    }
    return EOF;
}

int main(void)
{
    int fd;
    int result;
    struct med *map;  /* mmapped array of structs */

    /* Open a file for writing.
     *  - Creating the file if it doesn't exist.
     *  - Truncating it to 0 size if it already exists. (not really needed)
     *
     * Note: "O_WRONLY" mode is not sufficient when mmapping.
     */
    fd = open(FILEPATH, O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
    if (fd == -1)
    {
        perror("Error opening file for writing");
        exit(EXIT_FAILURE);
    }

    /* NB: ftruncate(fd, FILESIZE); is simpler */
    /* Stretch the file size to the size of the (mmapped) array of structs */
    result = lseek(fd, FILESIZE - 1, SEEK_SET);
    if (result == -1)
    {
        close(fd);
        perror("Error calling lseek() to 'stretch' the file");
        exit(EXIT_FAILURE);
    }

    /* Something needs to be written at the end of the file to
     * have the file actually have the new size.
     * Just writing an empty string at the current file position will do.
     *
     * Note:
     *  - The current position in the file is at the end of the stretched
     *    file due to the call to lseek().
     *  - An empty string is actually a single '\0' character, so a zero-byte
     *    will be written at the last byte of the file.
     */
    result = write(fd, "", 1);
    if (result != 1)
    {
        close(fd);
        perror("Error writing last byte of the file");
        exit(EXIT_FAILURE);
    }

    /* Now the file is ready to be mmapped.  */
    map = (struct med *)mmap(0, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (map == MAP_FAILED)
    {
        close(fd);
        perror("Error mmapping the file");
        exit(EXIT_FAILURE);
    }

    /* Input loop */
    int num_meds;
    for (num_meds = 0; num_meds < NUMINTS; num_meds++)
    {
        struct med m;
        memset(&m, '\0', sizeof(m));

        if (get_new_key(map, num_meds, &m.key) == EOF)
            break;

        printf("Name of med: ");
        if (scanf("%s", m.name) != 1)
            break;
        printf("Quant. min. of med: ");
        if (scanf("%d", &m.quant_min) != 1)
            break;
        printf("Quant. of med: ");
        if (scanf("%d", &m.quant) != 1)
            break;

        map[num_meds] = m;

        printf("Med %d saved.\n", m.key);
    }

    /* Output loop */
    printf("\nRecorded meds:\n");
    for (int i = 0; i < num_meds; i++)
    {
        char buffer[32];
        snprintf(buffer, sizeof(buffer), "M%.4d", i);
        print_med(buffer, &map[i]);
    }

    /* Don't forget to free the mmapped memory */
    if (munmap(map, FILESIZE) == -1)
    {
        perror("Error un-mmapping the file");
        /* Decide here whether to close(fd) and exit() or not. Depends... */
    }

    /* Un-mmapping doesn't close the file, so we still need to do that.  */
    close(fd);

    /* Remove file? */
    /* unlink(FILEPATH); */
}
1 Hydrocontin 3 5
1
2 Paxodontin 1 1
2
37 Ibuprofen 2 12
129 Butoxydione 12 29
4 Placebo 2 22
37
129
4
2
1
9231 Aspirin 99 99
$ ./mm7 < mm7.data
Key of med: Name of med: Quant. min. of med: Quant. of med: Med 1 saved.
Key of med: Med 1 already exists.
Key of med: Name of med: Quant. min. of med: Quant. of med: Med 2 saved.
Key of med: Med 2 already exists.
Key of med: Name of med: Quant. min. of med: Quant. of med: Med 37 saved.
Key of med: Name of med: Quant. min. of med: Quant. of med: Med 129 saved.
Key of med: Name of med: Quant. min. of med: Quant. of med: Med 4 saved.
Key of med: Med 37 already exists.
Key of med: Med 129 already exists.
Key of med: Med 4 already exists.
Key of med: Med 2 already exists.
Key of med: Med 1 already exists.
Key of med: Name of med: Quant. min. of med: Quant. of med: Med 9231 saved.
Key of med: 
Recorded meds:
M0000:    1: Q( 5, min  3): Hydrocontin
M0001:    2: Q( 1, min  1): Paxodontin
M0002:   37: Q(12, min  2): Ibuprofen
M0003:  129: Q(29, min 12): Butoxydione
M0004:    4: Q(22, min  2): Placebo
M0005: 9231: Q(99, min 99): Aspirin
$
$ odx /tmp/mmapped.bin
0x0000: 01 00 00 00 48 79 64 72 6F 63 6F 6E 74 69 6E 00   ....Hydrocontin.
0x0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0x0020: 03 00 00 00 05 00 00 00 02 00 00 00 50 61 78 6F   ............Paxo
0x0030: 64 6F 6E 74 69 6E 00 00 00 00 00 00 00 00 00 00   dontin..........
0x0040: 00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00   ................
0x0050: 25 00 00 00 49 62 75 70 72 6F 66 65 6E 00 00 00   %...Ibuprofen...
0x0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0x0070: 02 00 00 00 0C 00 00 00 81 00 00 00 42 75 74 6F   ............Buto
0x0080: 78 79 64 69 6F 6E 65 00 00 00 00 00 00 00 00 00   xydione.........
0x0090: 00 00 00 00 00 00 00 00 0C 00 00 00 1D 00 00 00   ................
0x00A0: 04 00 00 00 50 6C 61 63 65 62 6F 00 00 00 00 00   ....Placebo.....
0x00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0x00C0: 02 00 00 00 16 00 00 00 0F 24 00 00 41 73 70 69   .........$..Aspi
0x00D0: 72 69 6E 00 00 00 00 00 00 00 00 00 00 00 00 00   rin.............
0x00E0: 00 00 00 00 00 00 00 00 63 00 00 00 63 00 00 00   ........c...c...
0x00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
* (2484)
0x9C40:
$
0x0000: 01 00 00 00 48 79 64 72 6F 63 6F 6E 74 69 6E 00   ....Hydrocontin.
0x0010: 2F 62 69 6E 3A 2F 75 73 72 2F 67 6E 75 2F 62 69   /bin:/usr/gnu/bi
0x0020: 03 00 00 00 05 00 00 00 02 00 00 00 50 61 78 6F   ............Paxo
0x0030: 64 6F 6E 74 69 6E 00 00 2F 62 69 6E 3A 2F 75 73   dontin../bin:/us
0x0040: 72 2F 67 6E 75 2F 62 69 01 00 00 00 01 00 00 00   r/gnu/bi........
…
struct med m = { .key = 0, .name = "", .quant = 0, .quant_min = 0 };
0x0000: 01 00 00 00 48 79 64 72 6F 63 6F 6E 74 69 6E 00   ....Hydrocontin.
0x0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 2F 62 69   ............./bi
0x0020: 03 00 00 00 05 00 00 00 02 00 00 00 50 61 78 6F   ............Paxo
0x0030: 64 6F 6E 74 69 6E 00 00 00 00 00 00 00 00 00 00   dontin..........
0x0040: 00 00 00 00 00 2F 62 69 01 00 00 00 01 00 00 00   ...../bi........
…
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

#define FILEPATH "/tmp/mmapped.bin"
#define NUM_MEDS (1000)
#define FILESIZE (NUM_MEDS * sizeof(struct med))

struct med
{
    int key;
    char name[25];
    int quant_min;
    int quant;
};

static void print_med(const char *tag, const struct med *med)
{
    printf("%s: %4d: Q(%2d, min %2d): %s\n",
           tag, med->key, med->quant, med->quant_min, med->name);
}

static int med_in_map(const struct med *map, int num_meds, int key)
{
    for (int i = 0; i < num_meds; ++i)
    {
        if (key == map[i].key)
        {
            printf("Med %d already exists.\n", key);
            return 1;
        }
    }
    return 0;
}

static int get_new_key(const struct med *map, int num_meds, int *key)
{
    while (printf("Key of med: ") > 0 && scanf("%d", key) == 1)
    {
        if (med_in_map(map, num_meds, *key) == 0)
            return 0;
    }
    return EOF;
}

static int find_num_entries(const struct med *map, int max_meds)
{
    int i;
    for (i = 0; i < max_meds; i++)
    {
        if (map[i].key == 0)
            break;
    }
    return i;
}

int main(void)
{
    int fd;
    int result;
    struct med *map;

    fd = open(FILEPATH, O_RDWR | O_CREAT, (mode_t)0600);
    if (fd == -1)
    {
        perror("Error opening file for writing");
        exit(EXIT_FAILURE);
    }

    result = ftruncate(fd, FILESIZE);
    if (result == -1)
    {
        close(fd);
        perror("Error calling ftruncate() to 'set' the file size");
        exit(EXIT_FAILURE);
    }

    map = (struct med *)mmap(0, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (map == MAP_FAILED)
    {
        close(fd);
        perror("Error mmapping the file");
        exit(EXIT_FAILURE);
    }

    /* Input loop */
    int num_meds;
    for (num_meds = find_num_entries(map, NUM_MEDS); num_meds < NUM_MEDS; num_meds++)
    {
        struct med m;
        memset(&m, '\0', sizeof(m));

        if (get_new_key(map, num_meds, &m.key) == EOF)
            break;

        printf("Name of med: ");
        if (scanf("%s", m.name) != 1)
            break;
        printf("Quant. min. of med: ");
        if (scanf("%d", &m.quant_min) != 1)
            break;
        printf("Quant. of med: ");
        if (scanf("%d", &m.quant) != 1)
            break;

        map[num_meds] = m;

        printf("Med %d saved.\n", m.key);
    }

    /* Output loop */
    printf("\nRecorded meds:\n");
    for (int i = 0; i < num_meds; i++)
    {
        char buffer[32];
        snprintf(buffer, sizeof(buffer), "M%.4d", i);
        print_med(buffer, &map[i]);
    }

    /* Don't forget to free the mmapped memory */
    if (munmap(map, FILESIZE) == -1)
    {
        perror("Error un-mmapping the file");
        /* Decide here whether to close(fd) and exit() or not. Depends... */
    }

    /* Un-mmapping doesn't close the file, so we still need to do that.  */
    close(fd);
    return 0;
}


Share : facebook icon twitter icon
c - Struct in mmap

c - Struct in mmap


By : Chris Droste
Date : March 29 2020, 07:55 AM
I wish this help you Its pretty straight-forward -- you need to open the file, ensure that it is large enough, and then call mmap:
code :
int fd = open("/home/me/theMmap", O_RDWR|O_CREAT, 0660);
ftruncate(fd, sizeof(myStruct));
myStruct *Polo = mmap(0, sizeof(myStruct), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
mmap offset when using a struct

mmap offset when using a struct


By : user2828397
Date : March 29 2020, 07:55 AM
like below fixes the issue You should use pointer arithmetic on struct ip_row *data; to reach "further" in your mmaped shared memory since mmap returns nothing but a pointer to a memory region of FILESIZE, which happens to be mirrored into shared memory.
For example use data[0] to access first copy, data[1] to access second etc.
How to mmap a struct as shared anonymous memory?

How to mmap a struct as shared anonymous memory?


By : user3274310
Date : March 29 2020, 07:55 AM
This might help you According to what the OP answered in the comments, the output of the printf was:
code :
shm: redzone:0x10a0ad000. shmdata:0x10a0cb000. redzone:0x10a0cb000 end:0x10a0e9000
shm_pages = ((sizeof(struct shm_s) + page_size - 1) & PAGE_MASK) / page_size;
shm_pages = (sizeof(struct shm_s) + page_size - 1) / page_size;
Reading struct from mmap

Reading struct from mmap


By : Droidotech
Date : March 29 2020, 07:55 AM
it helps some times To put it simply, int has an alignment requirement. Supposing sizeof (int) is two on your machine, and we look at your memory as a sequence of blocks:
code :
[a][a][b][b][c][c][d][d]...
void serialise_st1(void *destination, st1 *source) {
    unsigned char *d = destination;
    unsigned long  s = (unsigned int) source->a;

    d[0] = s >> 8;
    d[1] = s;

    s = (unsigned int) source->b;
    d[2] = s >> 8;
    d[3] = s;

    s = source->ptr_to_st2;
    d[4] = s >> 24;
    d[5] = s >> 16;
    d[6] = s >> 8;
    d[7] = s;
}
void deserialise_st1(st1 *destination, void *source) {
    unsigned char *s = source;
    *destination = (st1) { .a = (s[0] <= 127 ? s[0] : -(256 - s[0])) * 0x0100
                              +  s[1],
                           .b = (s[2] <= 127 ? s[2] : -(256 - s[2])) * 0x0100
                              +  s[3],
                           .ptr_to_st2 = (s[4] <= 127 ? s[4] : -(256 - s[4])) * 0x01000000
                                       +  s[5] * 0x00010000
                                       +  s[6] * 0x00000100
                                       +  s[7] };
}
unsigned char *filemap;
st1 first;
deserialise_st1(&first, filemap);
st2 second;
deserialise_st2(&second, filemap + st1.ptr_to_st2);
serialise_st1(first_ptr, &st1);
serialise_st2(second_ptr, &st2);
c - can't read pointers from struct using mmap

c - can't read pointers from struct using mmap


By : Danny Chavez
Date : November 04 2020, 08:15 AM
hope this fix your issue How fast does this really need to be? Using a memory image for your persistent format is a problematic practice -- you need it to be a pretty big win in the larger scheme of things for it to be worthwhile, if it is even possible at all.
If you want a persistent representation of your data, then that representation needs to be self-contained. Pointers per se cannot be supported, but in their place you can use indexes into tables (effectively arrays) of objects. Better would be if indexing were implicit, but that may not be sufficient for you. I apologize for being vague, but I'd need to understand the characteristics of your data much better before I could suggest any specifics.
Related Posts Related Posts :
  • Data type conversion in Postfix evaluation
  • No output in terminal (Head First C)
  • Data writes over after realloc
  • function: findnextchar() doesn't work
  • Getting file-size property from Nautilus
  • Forward declare entities in C standard library?
  • Static array in C
  • Function signature indicates return type void*, but returns pointer of a different type
  • How do I measure time per thread in C?
  • Online judgeProblem (Wrong Answer)
  • Use function pointer initialized in other source file
  • last line of file is duplicated using fscanf
  • How to print files with same month of modification using directory in c?
  • ADT Circular Queue enqueue and dequeue
  • What events can cause ferror to return non-zero?
  • Accessing dynamically allocated structure received through socket
  • Vim with C Conditional Parsing
  • C can pointers be aligned with any other data type?
  • sdcc inline asm() not working
  • I/O - Manipulation of C Strings
  • sscanf 1 byte hex data without overflow
  • Avoid division by zero in C when taking log with respect to a random number
  • C - memory corruption with threads
  • Why does my program sometimes returns 0xc0000005 and sometimes runs well?
  • C - Dynamic array handling advice
  • Does Standard define null pointer constant to have all bits set to zero?
  • valgrind report strange memory usage
  • abs without branching, why this code works
  • Heapsort Algorithm by Cormen Implementation in C , not working correctly
  • C database program can't find 1st input. Why?
  • Generate random numbers with rand() except number zero
  • How can I know how many free bits are there in a pointer?
  • Program gets 101 numbers instead of 100
  • Returning array pointer produces "warning: return from incompatible pointer type"
  • Gauss Seidel (Specific equation solver) in C
  • Combine 4 chars into one unsigned long
  • Linked List pointer printing memory leak
  • My program won't do search function well. Why?
  • Varnish C VRT variables/functions
  • How can I concatenate strings in C?
  • Char with a variable length
  • Structure pointer pointing to different structure instance
  • Generate random string for member of struct
  • User Level Interrupt Handler for Timer
  • Generate random number for member in struct
  • Error: incompatible types when assigning to type ‘char[25]’ from type ‘char *’
  • Can't figure out why I am getting strange output
  • Condition checking inFor loop
  • segmentation fault due to initialize() function when changing the size of the huge page allocation
  • suspending an application preemptively before out of memory causes a segmentation fault
  • Should I use "rand % N" or "rand() / (RAND_MAX / N + 1)"?
  • C programming: Sorting a integer file while keeping their original place in file
  • Why I can't store/retrieve 11 digit long number properly
  • Out of bound array elements being printed using gcc in Win8
  • FIN-PSH-ACK server-side closure provoking RST from the client
  • Basic loop ends unexpectedly
  • PIC in C - creating own keypad scan routine using RC0-3
  • Does #if #endif act like scope?
  • Why is the -- operator not subtracting from the value when executed?
  • How i can disable maximal munch rule in Lex?
  • shadow
    Privacy Policy - Terms - Contact Us © ourworld-yourmove.org