我喜欢这个结构
struct free_bitmap{
int *node_bitmap;
int *data_bitmap;
}
我想将此结构复制到固定存储块并以二进制模式写入文件,然后从文件中读取此数据到固定存储块。而不是使用memcpy复制该数据到结构。
喜欢这个
struct free_bitmap f1;
struct free_bitmap f2;
f1.node_bitmap = (int *) malloc( sizeof(int) * 20 );
f1.data_bitmap = (int *) malloc( sizeof(int) * 128);
void * fblock = (void *) malloc(256);
memcpy((char*)fblock,(void*) &f1 ,256 );
int fd = open("test",O_RDWR|O_CREAT, 0600);
write(fd,fblock,256);
free(fblock);
我可以这样写数据,但是我不确定memcpy正在复制我的指针变量。并且我读取了文件,但是不起作用。
block = (void *) malloc(256);
lseek(fd, 0, SEEK_SET);
read(fd,fblock,256);
f2.node_bitmap = (int *) malloc( sizeof(int) * 20 );
f2.data_bitmap = (int *) malloc( sizeof(int) * 128);
memcpy((void*) &f2 , (char*)fblock , 256 );
free(fblock);
for(i=0;20>i;++i)
printf("%d " ,f1.node_bitmap[i]);
free(f2.node_bitmap);
free(f2.data_bitmap);
我的完整代码在这里Click
memcpy((char*)fblock,(void*) &f1 ,256 );
似乎memcpy
使您的代码失败。如果要复制该内容指针(或数组)的结构,则应为此结构的每个参数使用memcpy
。例如,如果要复制256个字节的struct到指针fblock
指向的地址,则指向:
memcpy(fblock,f1.node_bitmap ,20*sizeof(int));
// then copy the `256-20*sizeof(int)` by of `f1.data_bitmap` to `fblock`
memcpy(((uint8_t *))fblock + 20*sizeof(int),f1.data_bitmap ,256-20*sizeof(int));
// Note that, you should initialize the data in f1.data_bitmap before copying
如果要将f1.data_bitmap
和f1.node_bitmap
中的所有数据复制到fblock
,则必须为此指针至少分配128*sizeof(int) + 20 * sizeof(int)
个字节。
[要将数据复制到f2
结构时类似:
memcpy((void*) &f2 , (char*)fblock , 256 );
您可以更改为:
memcpy(f2.node_bitmap, fblock, 20*sizeof(int));
memcpy(f2.data_bitmap, (uint8_t *)fblock + 20*sizeof(int), 256 - 20 *sizeof(int));
您可以查看复制struct的更多信息:Copying one structure to another。
另一件事,您不应该强制转换malloc
函数:Do I cast the result of malloc?
如果代码喜欢memcpy(fblock,f1.node_bitmap ,20*sizeof(int));
,则不需要强制转换源指针和目标指针,因为memcpy
不在乎数据类型,它在乎源地址,目标地址和数据量您要复制的内容。
我想将此结构复制到固定存储块并以二进制模式写入文件,然后从文件中读取此数据到固定存储块。而不是使用memcpy复制该数据到结构。
您确实不需要创建中间缓冲区。只需直接读取/写入该结构即可。您可以通过对每个“保存/还原”操作进行two读取或写入操作来完成此操作。有时称为“序列化”
它更简单,更快捷,不需要memcpy
。
这是重构您的代码以实现的目标:
#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:
我是说我想像文件系统一样使用此文件。例如,将此结构写入第一个块,将另一个结构写入第二个块,块大小为2kb。因此,我使用堆内存来修复数据长度。文件大小固定为1Mb,例如]
好,这是一个编写multiple块并比较结果的版本。它将每个对齐为2KB的块大小,总大小为1MB:
#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;
}