In article <11*********************@g49g2000cwa.googlegroups. com>,
<nk******@gmail.com> wrote:
I have a following structure:
typedef struct
{
RateData rdr;
int RateID;
char RateBalance;
} RateInfo;
typedef struct
{
DayRates *dr;
WeekRates *wr;
} RateData;
First I will create the memoefy for the DayRates, WeekRates structures
inside the RateInfo structure variable.
Once the total tree is contructed,
I will store this tree as file (rateinfo.map) on the disk.
In my next programming component, Iam going to load this file
(rateinfo.map) into memory using mmap() function call. Once I load the
file into memory using mmap(), Iam able to access the RateID and
RateBalance members of the RateInfo. But, Iam not able to access the
DayRates, and WeekRates structure contents.
It is not clear from what you wrote whether the "next programming
component" is running in the same process that created the stored tree,
and it is not clear as to whether you released the memory for the
tree between the two parts.
When you write out the tree to a file, you are writing the raw binary
pointer values (DayRates *)dr and (WeekRates *)wr. Those pointer values
are to active memory. If you release that memory, either by freeing it
or overwriting it or by exiting the process, then the referrants of
the pointers cease to exist. If you then bring back the binary values
via the mmap() and try to use the stored pointers, you are going to
be pointing to some random thing. You were lucky in a way to get a
segment fault, because that made it clear that you were doing something
wrong; it would have been worse if there hadn't been any fault and
you ended up using the random data.
In general, there is no way to store and restore pointers between
sessions. What people often do instead is to allocate one big
block of memory to start with, then use their own malloc() and free()
routines to ensure that memory related to that purpose is taken from
that block of memory. Then when it is time to write the data out, they
convert each pointer into an offset from the beginning of the data
structure. When they want to load the data structure back in again,
they reverse the process, allocating a block of memory, and converting
each stored offset into a pointer by adding in the address of the
new instance of the memory block.
There is sometimes another option, that is not portable in terms of
the C standard, but possible if you are willing to restrict execution
to a particular OS and architecture. In the variant I am thinking of,
possible in a number of unix-like systems [but not in C in general],
you can use mmap() to allocate new memory into a fixed virtual address.
You would then do your own malloc() and free() as per the above
(or possibly you might find an extension malloc library to do it for you).
When you finished constructing the tree, you would then save the mmap()
block to a file. Then to restore the tree into a different process on
the same kind of system, you would mmap() the file contents into the
exact same virtual address as was used originally. The pointers would
then all become valid because the contents and virtual addresses would
have been restored.
This option does, of course, assume that your operating system supports
virtual memory, and supports mmap() as a way of allocating new memory,
and supports mmap() of a file to a user- specified virtual address, and
assumes that whatever system the file is restored into has the
same representation of all the types (including pointers!) as the
data was created upon...
--
All is vanity. -- Ecclesiastes