newing pointers

Started by
14 comments, last by Orpheum 23 years, 10 months ago
I have an array of struct pointers that I want to dynamically allocate when a record needs to be read in from a file. The allocation is going to be random so it makes things a little more tricky. When strctptr* is ready to be allocated, I use the statement ''strctptr = new structure;''. This is all fine and dandy, but when I try to read the struct from the file using ''in.read((char*) strctptr, sizeof(structure));'', I get an Access Violation. Considering there is WAAAAAY more data in the file than sizeof(structure), I can only assume I''m not allocating the strctptr array correctly… </i>
There is no spoon.
Advertisement
and you open your file in binary mode ??
i had many sleepless hours trying to find that error =)
Ries
I am already doing that... =(
There is no spoon.
is it the read that crashes the app ??

if not, are there pointers in the structure that you use after loading it, without assign them to something ??

or paste a little more code =), i dont see why that what you posted not should work.

except that the file you open isn't invalid (failed to open) or the content of the file is not vaild.


Edited by - Claus Hansen Ries on June 21, 2000 3:00:30 AM
Ries
quote:Original post by Orpheum

Considering there is WAAAAAY more data in the file than sizeof(structure), I can only assume I''m not allocating the strctptr array correctly...


If there is way more data in the file than sizeof(structure), then your problem is not in your allocation, it''s in the fact that you''re writing out your structure differently to how you''re reading it in. Perhaps you are writing out lots of strings in the structure individually and expecting to be able to read them right back in with one call to read()? Because that is not going to work.

Yes, the problem is on the read() statment... The struct is written to the file out.write((char*) &MyStruct, lEntrySizes );
The MyStruct struct contains the following data members:

int iIndex;
_filedata_t fileinfo;
BITMAP BMP;

I wish sizeof(MYSTRUCT) worked, but the BITMAP struct is dynamically allocated and sizeof() wont work with dynamic memory. lEntrySizes is sizeof(MYSTRUCT) + fileinfo.size (of the bitmap file). I've measured this all out, and it is correct. The only thing I can think that would be causing this error is not enough mem is being allocated to hold the struct thats being read in... or that I not 'new'ing the pointers right and its barfing on that.

Here is some more code...

MYSTRUCT mystruct*[256];
bool tilecached[256];
WORLD myworld*;
ifstream in("tiles.set", ios::binary / ios::nocreate);

myworld = new WORLD[mapheader.numgrids];

int i = 0;
int j = 0;
while(i < mapheader.numgrids)
{
while(j < world.tilecount)
{
if(tilecached[world.tileindex[j]] != true) //dont realloc<br>{<br>mystruct = new MYSTRUCT; //should maybe be *mystruct, or &??<br>in.seekg(mapheader.byteoffsets, ios::beg);<br>in.read((char*) mystruct, mapheader.lEntrySizes) //Access Violation here<br>tilecached = true;<br>}<br>j++;<br>}<br>i++;<br>j = 0; //start over for next tileindex<br>}<br><br><br>Hopefully thats not too confusing… I just want to read in a struct of size mapheader.lEntrySizes into mystruct, which is dynamically allocated if world.tileindex[j] has not allready been cached in mystruct. </i> <br><br>Edited by - Orpheum on June 21, 2000 1:00:25 PM<br><br>Edited by - Orpheum on June 21, 2000 4:07:40 PM
There is no spoon.
Here is what i think what happens

one thing, the line:
tilecached == true;<br><br>does nothing, its just true =)<br>i think you ment: <br>tilecached = true;<br><br>Second,<br>out.write((char*) &MyStruct, lEntrySizes );<br>where lEntrySizes = sizeof(MYSTRUCT) + fileinfo.size (of the bitmap file). <br><br>This only saves the struct + garbage after the struct<br><br>the BITMAP structure holds a pointer to a memory area, "bmBits"<br>THE POINTER IS SAVED, NOT THE AREA IT POINTS TO !!!!<br><br>so when you save the struct you save<br><br>———— file ———<br>int iIndex;<br>_filedata_t fileinfo;<br><br> LONG bmType; // the bitmap struct<br> LONG bmWidth; <br> LONG bmHeight; <br> LONG bmWidthBytes; <br> WORD bmPlanes; <br> WORD bmBitsPixel; <br> LPVOID bmBits; // here you only store the void pointer, not what it points to<br><br>ALLOT OF GARBAGE HERE, because of lEntrySizes<br>—– file end ——-<br><br>now when you load it again, you allocated a mystuct using new.<br><br>—– mystruct alloc in mem —–<br>int iIndex;<br>_filedata_t fileinfo;<br><br> LONG bmType; // the bitmap struct<br> LONG bmWidth; <br> LONG bmHeight; <br> LONG bmWidthBytes; <br> WORD bmPlanes; <br> WORD bmBitsPixel; <br> LPVOID bmBits; // here you only load the void pointer that points to some non existant data<br>—— end —————– UPS here you start to load the garbage data, mystuct is not larger<br><br>************* other data ****************<br><br>————————-<br><br>now since you fill the other data area with the garbage, ACCESS VIOLATION…<br><br>so when you load the struct you actually load a pointer to at memory area that doesn't exist anymore. + fill other data with garbage.<br><br>hope it wasn't too CHAOTIC =)<br> <br><br>Edited by - Claus Hansen Ries on June 21, 2000 1:24:32 PM<br><br>Edited by - Claus Hansen Ries on June 21, 2000 1:26:14 PM
Ries
I think the problem is that you have to allocate the memory for the array of pointers, and then allocate memory for each pointer as well.

For instance, if you have 10 structures in a file, and you want to read them, you need to do things this way:

structure **strctptr;strctptr = new structure* [10]; // allocates 10 pointers to arrayfor (int idx=0; idx<10; idx++)  strctptr[idx] = new structure; // allocate structure to pointer  


Now you can do your read inot strctptr .

By the way, to cleanup this array, you'd have to do this:
for (int idx=0; idx<10; idx++)  delete strctptr[idx]; // delete each structure memorydelete [] strctptr; // delete array memory 


The problem is that you don't know ahead of time how many structures there will be in the file, so you don't know how much room to allocate. There are two ways to do this:
1) When you save your file, first write the number of structures to the file. That way, when loading, you can first load how many structures you expect, then allocate that much space in memory.
2) Use a dynamically-growing array class (i.e. std::vector) and read until the end of the file.

I prefer method #1 because it will let you mix different types into the same file, and it's easy to look through the file in hex mode and figure out what's going on.

Hope that helps.

Edited by - Stoffel on June 21, 2000 2:53:59 PM
Hmm... thats an interresting theory, I will have to investigate when I get home... If indeed that is what Im doing, how would you suggest I fix it? 2 ofstream::write() calls?

out.write((char*) &mystruct, sizeof(MYSTRUCT);
out.write((char*) *mystruct.bmp.bmbits, sizeof(*mystruct.bmp.bmbits);
Hmm... thats an interresting theory, I will have to investigate when I get home... If indeed that is what Im doing, how would you suggest I fix it? 2 ofstream::write() calls?

out.write((char*) &mystruct, sizeof(MYSTRUCT);
out.write((char*) *mystruct.bmp.bmbits, sizeof(*mystruct.bmp.bmbits);

This topic is closed to new replies.

Advertisement