Yes, that's pretty much you will need to do - adjust pointers to serialized stuff, if you keep any. Or simply don't store any pointers to serialized data, just indices, then doing fread/fwrite will be everything you need to do.
I know people don't like C++ much here, but if you want then for serializing pointers you could use this helper template:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | template <class T>
struct Pointer32
{
int32_t offset;
T* operator ()
{
return (T*)((uint8_t*)this + offset));
}
Pointer32& operator = (T* other)
{
ptrdiff_t diff = (uint8_t*)other - (uint8_t*)this;
assert(diff>= INT_MIN && diff <= INT_MAX);
offset= (int32_t)diff;
return *this;
}
};
|
This will allow to write code like this:
1
2
3
4
5
6
7
8
9
10
11
12
13 | struct Blob
{
float x;
float y;
Pointer32<Blob> next;
};
Blob* blob = ...; // unserialize
blob->x = 1;
blob->next->x = 2; // here we reference other object by relative offset
Blob* otherBlob = ...;
blob->Next = otherBlob; // change pointer
|
C++ will automatically resolve pointer from relative offset. And if you can guarantee that you are placing objects closer together you can create Pointer16 with int16_t offset, saving 2 bytes. Even just by using Pointer32 you will save 4 bytes per pointer on 64-bit architecture.
And you can easily fread/fread whole memory block that stores Blob's as array of bytes.
And because pointers are typically aligned at least at 4 or even 8 bytes, you can increase distance 4 or 8 types by always using 0 as lowest bits of offset and shifting it up 2 or 3 bits.
And if you are OK using MSVC specifc syntax you can look into
__based keyword, but I recomend against using it and staying portable.