Need help to find cause of error. (file loading)
I am going INSANE over this stupid problem! I am trying to load a 3DS file, and I get this memory violation access memory where I shouldn't even have one!
OFSTRUCT of;
HFILE hfile;
int filesize=0;
BYTE *file_mesh;
CModel_3DS_Chunk chunk;
---File is found---
hfile = OpenFile(filename,&of,OF_READ);
---First chunk is being read and works--
_lread(hfile,&chunk.id,sizeof(short int));
_lread(hfile,&chunk.size,sizeof(unsigned int));
---file memory pool is created---
file_mesh = new BYTE[chunk.size];
---The file is read (what's left of it)---
_lread(hfile,file_mesh,sizeof(BYTE)*chunk.size);
---Everything ok so far. The file's closed---
_lclose(hfile);
while(file_mesh)
{
---And here I get a memory violation error---
chunk.id = (short int)(*file_mesh); <--- BAM! Error!
file_mesh++;
chunk.size = (unsigned int)(*file_mesh);
file_mesh++;
Any ideas?
Js
The problem could be that your incrementing your file_mesh pointer past the size of the array.
As far as I can tell that last cycle will never end. Besides for each cycle you add 2 to file_mesh, is that correct?
The error is probably what Hylo said.
The error is probably what Hylo said.
This looks like its not the complete while-part. So you leave us with guessing what you are trying to do.
But from what I see, you use the mesh-pointer wrong in two ways:
1. Error: while(file_mesh)
This will always be true, except when the new fails. You have allocated a valid pointer and you can increment it as long as you like, no matter how much memory you actually allocated. The pointer does NOT go null when it reaches the end of your allocated memory.
You need something like:
BYTE *end_ptr = file_mesh + chunk.size;
while( file_mesh < end_ptr)
[...]
2. Error
You treat the first BYTE from file_mesh as if it was the chunk-id and the second as if it was the chunk-size. I assume that BYTE is a one-char type (could be wrong here), short int is 2 bytes and long int is 4 bytes. You are trying to cast the first BYTE of the mesh into a short-int and the second BYTE into long-int. Sure the cast itself technically works, but it is not the result you might expect.
Additionally you already read the chunk into your chunk-structure before you read the file_mesh. So chunk-id and chunk-size are not in the file_mesh itself.
3. Error: Wrong mesh_reading.
The chunk.size contains the whole size of the chunk _including_ the chunk-header itself. So you read too much bytes into your file_mesh. The read should be like:
_lread(hfile,file_mesh,(sizeof(BYTE)*chunk.size)-sizeof(CModel_3DS_Chunk));
BTW, why use 2 reads for the chunk? It could be done in one read like:
_lread(hfile,chunk,sizeof(CModel_3DS_Chunk));
PS: Use a debugger, it helps...
But from what I see, you use the mesh-pointer wrong in two ways:
1. Error: while(file_mesh)
This will always be true, except when the new fails. You have allocated a valid pointer and you can increment it as long as you like, no matter how much memory you actually allocated. The pointer does NOT go null when it reaches the end of your allocated memory.
You need something like:
BYTE *end_ptr = file_mesh + chunk.size;
while( file_mesh < end_ptr)
[...]
2. Error
You treat the first BYTE from file_mesh as if it was the chunk-id and the second as if it was the chunk-size. I assume that BYTE is a one-char type (could be wrong here), short int is 2 bytes and long int is 4 bytes. You are trying to cast the first BYTE of the mesh into a short-int and the second BYTE into long-int. Sure the cast itself technically works, but it is not the result you might expect.
Additionally you already read the chunk into your chunk-structure before you read the file_mesh. So chunk-id and chunk-size are not in the file_mesh itself.
3. Error: Wrong mesh_reading.
The chunk.size contains the whole size of the chunk _including_ the chunk-header itself. So you read too much bytes into your file_mesh. The read should be like:
_lread(hfile,file_mesh,(sizeof(BYTE)*chunk.size)-sizeof(CModel_3DS_Chunk));
BTW, why use 2 reads for the chunk? It could be done in one read like:
_lread(hfile,chunk,sizeof(CModel_3DS_Chunk));
PS: Use a debugger, it helps...
1. Error: while(file_mesh)Thanks for this tidbit =)
You need something like:
BYTE *end_ptr = file_mesh + chunk.size;
while( file_mesh < end_ptr)
[...]
2. Error Also helpful! Thanks!
3. Error: Wrong mesh_reading.
BTW, why use 2 reads for the chunk? It could be done in one read like:
_lread(hfile,chunk,sizeof(CModel_3DS_Chunk));
Because I've tried that with other files, and gotten errors. Apparently the compiler puts in additional memory i class{} and struct{} to make sure data errors don't occur.
PS: Use a debugger, it helps...
I do, I just don't always see what it's trying to tell me =)
You need something like:
BYTE *end_ptr = file_mesh + chunk.size;
while( file_mesh < end_ptr)
[...]
2. Error Also helpful! Thanks!
3. Error: Wrong mesh_reading.
BTW, why use 2 reads for the chunk? It could be done in one read like:
_lread(hfile,chunk,sizeof(CModel_3DS_Chunk));
Because I've tried that with other files, and gotten errors. Apparently the compiler puts in additional memory i class{} and struct{} to make sure data errors don't occur.
PS: Use a debugger, it helps...
I do, I just don't always see what it's trying to tell me =)
Js
Quote: Original post by the_recon
Because I've tried that with other files, and gotten errors. Apparently the compiler puts in additional memory i class{} and struct{} to make sure data errors don't occur.
Hehe, you work around a problem instead of solving it :)
Your problem with loading comes from the default packing alignment.(search fpr packing in msdn) Lets assume you use this struct:
struct test { short id; long size;};
Than you expect the short to be 2 byte and the long to be 4 byte long, so the total size of this struct would be 6.
Assuming that your compilers packing alignment is set to 4 byte, the struct would be 8 bye of size instead, because every var will be at least 4 byte big. In case of the short-variable, there will be 2 bytes padded so it sums up to 4 byte.
For your purpose of loading this struct properly, you have to set the packing alignment to 1 byte, so that no bytes will be padded at all.
#pragma pack( push, packing ) // safe the standart alignment#pragma pack( 1 ) // set alignment to 1 bytestruct test { short id; long size;};#pragma pack( pop, packing ) // reset to standart alignment
With packing alignment set to 1 Byte you will be able to load the struct with one read instead of several.
Cool! I was not at all aware of that =) The book I learned from simply told me about the padding, but nothing on how to modify this! =)
Js
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement