大家好抱歉,但我能找到合适的解决方案。 我正在开发一个文件系统,我将每个文件节点保存为GDBM数据库中的键值对。 我有一个具有一些属性的结构,我将其转换为字节数组
struct mystruct:
typedef struct nold{
char* name;
char* surname;
int age;
}mystruct;
我将其转换为字节数组
dead.name="john";
dead.surname="doe";
dead.age=22;
//copy bytes of the our struct
char buffer[sizeof(dead)];
memcpy(buffer, &dead, sizeof(dead));
存储在数据库中我们使用的数据结构如下:
typedef struct {
char *dptr;
int dsize;
} datum
我填写基准结构如下:
//create a key datum
char* k="file.txt";
key.dptr=k;
key.dsize=strlen(k)+1;
//create a value datum here I assign bytes
value.dptr=buffer;
value.dsize = sizeof(dead);
现在我将GDBM存储为键值对
然后在另一个文件中,我读取了我存储的数据并尝试将其重新转换回结构
datum result;
//read
result=gdbm_fetch(file,key);
char* bytes=result.dptr;
mystruct* reborn;
reborn=(mystruct*)bytes;
//print from our new struct
printf("%s\n",reborn->name);
printf("%s\n",reborn->surname);
printf("%d\n",reborn->age);
它打印以下内容:
E���D$�$ˈ�k����E��
$�$ˈ�k����E��
22
它设法恢复结构但是char *的数据丢失了。仅涵盖整数数据。知道为什么会这样吗?怎么解决?它不能通过存储一个字节数组来解决,将字节数组转换为十六进制或base64,并将其存储起来。
我真的在挣扎这个。请提前谢谢你。
答案 0 :(得分:2)
struct中的指针只是一个指向字符数组的指针而不是字符数组本身:
typedef struct nold{
char* name;
char* surname;
int age;
}mystruct;
mystruct s;
s.name = "Salam";
这将为字符串“Salam”保留一个内存空间,将字符串Salam放入并返回指向s.name的指针。
现在你正在将整个结构复制到其他东西中,你从结构地址复制sizeof(mystruct)实际上不是保持字符串“Salam”,它只是一个指向“Salam”的指针。
如果您想这样做,您必须预先为名称分配一些空格:
#define MAX_NAME_LEN 50
typedef struct nold{
char name[MAX_NAME_LEN];
char surname[MAX_NAME_LEN];
int age;
}mystruct;
mystruct s;
strcpy(s.name, "Salam");
现在memcpy将起作用
mystruct d;
memcpy(&d, &s, sizeof(mystruct);
答案 1 :(得分:2)
指针值仅在特定程序的特定运行的上下文中有意义。可以编写它们并将它们读回来,但必须记住指针指定一个地址,而不是(直接)驻留 at 该地址的数据,如果地址确实有效的话对于访问它的程序。您不通过传送指针来传达进程之间的指向数据。
您可以通过将要传达的数据直接放入结构中来解决问题:
typedef struct {
char data[MAX_DATA_SIZE];
int dsize;
} datum;
这种方法的缺点是你必须在数据大小上设置一个固定的上限,但在很多情况下这不是问题。如果您需要无限制的数据,那么您需要一种完全不同的方法。
答案 2 :(得分:1)
问题是name和surname是指向字符串文字的指针。所以你的struct不包含字符串本身,而是指向文字所在的数据部分的指针。只要将其复制到缓冲区,您实际上只是复制指针值。重建后,这些指针值现在指向一些不包含字符串的任意区域。
编辑:这是一个将数据传输到缓冲区的函数:
size_t copyMyStructToBuffer(mystruct *aPerson, char **buffer) {
size_t nameLen = strlen(aPerson->name);
size_t surnameLen = strlen(aPerson->surname);
size_t structLen = nameLen + 1 + surnameLen + 1 + sizeof(int);
*buffer = malloc(structLen);
memcpy(*buffer, aPerson->name, nameLen + 1); // w/ terminator
memcpy((*buffer)[nameLen+1], aPerson->surname, surnameLen + 1); // w/ terminator
memcpy((*buffer)[nameLen+1+surnameLen+1], &aPerson->age, sizeof(int));
return structLen;
}
以及如何使用它:
mystruct dead;
dead.name = "John";
dead.surname = "Doe";
dead.age = 22;
char *buff;
size_t buffLen;
buffLen = copyMyStructToBuffer(&dead, &buff);
// use buff here
free(buff);
不可否认,这段代码很难维护。