我想将结构的状态保存为二进制文件并再次加载它们。 我的结构看起来像这样:
typedef struct
{
uint8_t pointerLength;
uint8_t *pointer;
uint8_t NumBla;
uinT16 Bla[MAX_NUM_Bla];
...
}
BAR_STRUCT, *BAR;
typedef struct
{
int numBar;
BAR bars[MAX_NUM_BAR];
}
FOO_STRUCT, *FOO;
保存没问题,但恢复状态。 Iam在文件的字节串在堆上并且指针指向该字符串的第一个地址的位置。 我这样做:
const void* dataPointer //points to adress in heap
unsigned char* bytePointer = (unsigned char*)dataPointer;
FOO foo = (FOO_STRUCT*)bytePointer;
bytePointer += sizeof(FOO_STRUCT);
for (int i=0; i < MAX_NUM_BAR; i++) {
foo->bars[i] = (BAR_STRUCT*)bytePointer;
}
最后一项任务无效,我获得了EXC_BAD_ACCESS
因为bars是一个指针数组,我需要纠正每个元素指向的地址。因为它们不再有效。所以我尝试将我保存在bytesteam中的对象的地址分配给foo-&gt; bars [i];
但我根本无法改变foo-&gt; bars [i]。访问作品,但分配新的地址不
我想知道为什么。
编辑:
我在OSX上工作以便将字节写入文件我使用NSData:
bool saveCurrentState( FOO foo){
NSMutableData *data = [NSMutableData data];
[data appendBytes:templates length:sizeof(FOO_STRUCT)];
for (int i=0; i < MAX_NUM_BAR; i++){
[data appendBytes:&foo->bar[i] length:sizeof(INT_BAR_STRUCT)];
if( foo->bar[i] != NULL )
[data appendBytes:foo->bar[i]->pointer length:sizeof(uint8_t)*foo->bar[i]->length];
...
}
}
我无法真正更改结构,因为它们在lib中使用,我实际上也无法访问它。我特别感兴趣的是它没有按预期工作。 如您所见,我复制整个结构,包括指针本身,并添加指针指向字节字符串的结构。希望这能给你一点澄清。
当读取字节流来设置结构时,我只需要用新地址更改数组的值,并且由于某种原因不想工作。
编辑: 我也用NSData保存/读取文件:
NSData* data = [NSData dataWithContentsOfFile:@"path/to/file"];
const void* dataPointer = [data bytes];
答案 0 :(得分:2)
看起来你所追求的是一个序列化库。尝试protocol buffers或tpl之类的内容(选择取决于您的确切需求,请查看文档)。
这previous question似乎在解决一些问题上做得不错。
答案 1 :(得分:1)
除了使用@ Yaniv建议的序列化之外,您可以做的是将所有内容存储在平面内存中,以避免嵌入指向单独内存位置的指针:
class Foo
{
private:
// Prevent direct instantiation
Foo();
int numBar;
public:
struct Bar
{
int pointerLength;
int numBlas;
uint16 blas[MAX_NUM_Bla];
uint8* GetPointer()
{
return reinterpret_cast<uint8*>(this + 1);
}
};
// Factory method
static Foo* Create()
{
int totalSize = sizeof(Foo) + /* total size of all the Bars */;
Foo* pFoo = reinterpret_cast<Foo*>(new char[totalSize]);
...
}
};
请注意,不再有Bar :: pointer成员,而是Bar :: GetPointer方法。那是因为指针指向的东西将改为Bar的成员的记忆之后,所以一切都是平的。同样,Foo中的Bars数组将紧跟在Foo成员的记忆之后。