I want to copy this struct to fixed memory block and write to file with binary mode and read this data from file to fixed memory block.And than copy this data with memcpy to struct.
You really don't need to create an intermediate buffer. Just read/write directly to the struct. You do this by doing two reads or writes for each "save/restore" operation. This is sometimes called a "serialization"
It's simpler and faster and doesn't need memcpy
.
Here's your code refactored to do that:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
enum {
NODECOUNT = 20,
DATACOUNT = 128,
};
struct free_bitmap {
int *node_bitmap;
int *data_bitmap;
};
void
bitmap_alloc(struct free_bitmap *f)
{
f->node_bitmap = malloc(sizeof(int) * NODECOUNT);
f->data_bitmap = malloc(sizeof(int) * DATACOUNT);
}
void
bitmap_free(struct free_bitmap *f)
{
free(f->node_bitmap);
free(f->data_bitmap);
}
void
bitmap_write(int fd,struct free_bitmap *f)
{
write(fd,f->node_bitmap,sizeof(int) * NODECOUNT);
write(fd,f->data_bitmap,sizeof(int) * DATACOUNT);
}
void
bitmap_read(int fd,struct free_bitmap *f)
{
read(fd,f->node_bitmap,sizeof(int) * NODECOUNT);
read(fd,f->data_bitmap,sizeof(int) * DATACOUNT);
}
int
main()
{
struct free_bitmap f1;
struct free_bitmap f2;
bitmap_alloc(&f1);
int i;
for (i = 0; i < NODECOUNT; ++i)
f1.node_bitmap[i] = i;
int fd = open("test", O_RDWR | O_CREAT, 0600);
bitmap_write(fd,&f1);
printf("a");
lseek(fd, 0, SEEK_SET);
bitmap_alloc(&f2);
bitmap_read(fd,&f2);
for (i = 0; i < NODECOUNT; ++i)
printf("%d ", f1.node_bitmap[i]);
printf("\n");
bitmap_free(&f1);
bitmap_free(&f2);
return 0;
}
UPDATE:
I mean I want to use this file like a file system. For example Write this struct to first block and another struct to second block and Block size 2kb.So I use the heap memory to fix data lenght.File size fixed and 1Mb for example
Okay, here's a version that writes multiple blocks and compares the results. It aligns each to a block size of 2KB, using a 1MB total size:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
enum {
NODECOUNT = 20,
DATACOUNT = 128,
BLOCKSIZE = 2 * 1024,
FILESIZE = 1024 * 1024,
NMAP = 5,
};
struct free_bitmap {
int *node_bitmap;
int *data_bitmap;
};
void
bitmap_alloc(struct free_bitmap *f)
{
f->node_bitmap = malloc(sizeof(int) * NODECOUNT);
f->data_bitmap = malloc(sizeof(int) * DATACOUNT);
}
void
bitmap_free(struct free_bitmap *f)
{
free(f->node_bitmap);
free(f->data_bitmap);
}
void
bitmap_write(int fd,struct free_bitmap *f)
{
ssize_t tot = 0;
tot += write(fd,f->node_bitmap,sizeof(int) * NODECOUNT);
tot += write(fd,f->data_bitmap,sizeof(int) * DATACOUNT);
tot = BLOCKSIZE - tot;
if (tot > 0)
lseek(fd,tot,SEEK_CUR);
}
void
bitmap_read(int fd,struct free_bitmap *f)
{
ssize_t tot = 0;
tot += read(fd,f->node_bitmap,sizeof(int) * NODECOUNT);
tot += read(fd,f->data_bitmap,sizeof(int) * DATACOUNT);
tot = BLOCKSIZE - tot;
if (tot > 0)
lseek(fd,tot,SEEK_CUR);
}
int
mapcmp(int mapidx,const char *tag,const int *lhs,const int *rhs,int count)
{
int i;
int bad = 0;
for (i = 0; i < count; ++i) {
if (lhs[i] != rhs[i]) {
printf("mapcmp: MISMATCH mapidx=%d tag=%s i=%d lhs=%d rhs=%d\n",
mapidx,tag,i,lhs,rhs);
bad = 1;
}
}
return bad;
}
int
main(void)
{
struct free_bitmap wlist[NMAP];
struct free_bitmap *wcur;
struct free_bitmap rlist[NMAP];
struct free_bitmap *rcur;
int off;
int i;
int mapidx;
int code;
int fd = open("test", O_RDWR | O_CREAT, 0600);
ftruncate(fd,FILESIZE);
// create blocks with unique test data
off = 0;
for (wcur = &wlist[0]; wcur < &wlist[NMAP]; ++wcur, off += 23) {
bitmap_alloc(wcur);
for (i = 0; i < NODECOUNT; ++i)
wcur->node_bitmap[i] = i + off;
for (i = 0; i < DATACOUNT; ++i)
wcur->data_bitmap[i] = i + off + 17;
bitmap_write(fd,wcur);
}
lseek(fd, 0, SEEK_SET);
for (rcur = &rlist[0]; rcur < &rlist[NMAP]; ++rcur) {
bitmap_alloc(rcur);
bitmap_read(fd,rcur);
}
code = 0;
// compare all data in all blocks
for (mapidx = 0; mapidx < NMAP; ++mapidx) {
wcur = &wlist[mapidx];
rcur = &rlist[mapidx];
if (mapcmp(mapidx,"NODE",rcur->node_bitmap,wcur->node_bitmap,NODECOUNT))
code = 1;
if (mapcmp(mapidx,"DATA",rcur->data_bitmap,wcur->data_bitmap,DATACOUNT))
code = 1;
}
// release all blocks
for (mapidx = 0; mapidx < NMAP; ++mapidx) {
bitmap_free(&wlist[mapidx]);
bitmap_free(&rlist[mapidx]);
}
printf("%s\n",code ? "FAIL" : "PASS");
return code;
}