Sign in to follow this  
Lord_Vader

Can anyone help me with this code?

Recommended Posts

The problem is that the fread funcion doesnt read the file when I try to dynamically allocate the memory(it throws exceptions): I have a class, with some pointers for example
.
.//In the class
.
private:
polygon_class* polygons;
.
.
.

and a function in that class like:
.
.
.
//Code within a classes function

		case 0x4120:
				fread (&numofP, sizeof (unsigned short), 1, l_file);
                this->num0fpolygons = numofP;

				polygons = new polygon_class[numofP];

					fread (&polygon[i].a, 2, 1, fileP);
					fread (&polygons[i].b, 2, 1, fileP);
					fread (&polygons[i].c, 2, 1, fileP);
					fread (&flags, 2, 1, fileP);
	
				}
                break;
.
.
.

the polygon class is:
class polygon_class
{
public:
	unsigned int a,b,c;
};
when I try the same using arrays instead of the pointer it works! any ideas?I am desperate

Share this post


Link to post
Share on other sites

fread (&polygon[i].a, 2, 1, fileP);
fread (&polygons[i].b, 2, 1, fileP);
fread (&polygons[i].c, 2, 1, fileP);

What is i, and what is polygon?

That code shouldn't even compile, you've got a random closing brace. That brace probably refers to the for loop you didn't bother posting. If you want help finding bugs in your code, please post your code. Not a few random lines that don't make any sense.

CM

Share this post


Link to post
Share on other sites
I am sorry
Here is the whole function:


char Model::LoadModel(char *filename)
{
int i;

FILE *file;

unsigned short chunk_id;
unsigned int chunk_length;

unsigned char char;
unsigned short howmany = 0;
unsigned short flags = 0;

if (fopen_s(&file,filename, "rb"))
return 0;

while (ftell(file) < _filelength (_fileno (file)))
{

fread (&chunk_id, 2, 1, file);
fread (&chunk_length, 4, 1, file);

switch (chunk_id)
{

case 0x4d4d:
break;
case 0x3d3d:
break;
case 0x4000:
i=0;
do
{
fread (&char, 1, 1, file);
this->name[i]=char;
i++;
}while(char != '\0' && i<20);
break;
case 0x4100:
break;

case 0x4110:
fread (&howmany, sizeof (unsigned short), 1, file);
this->vertices_qty = howmany;

vertex = new vertex_class[vertices_qty];
{
fread (&vertex[i].x, sizeof(float), 1, file);
fread (&vertex[i].y, sizeof(float), 1, file);
fread (&vertex[i].z, sizeof(float), 1, file);
}
break;


case 0x4120:
fread (&howmany, sizeof (unsigned short), 1, file);
this->polygons_qty = howmany;

polygons = new polygon_class[howmany];

for (i=0; i<howmany; i++)
{
fread (&polygons[i].a, 2, 1, file);
fread (&polygons[i].b, 2, 1, file);
fread (&polygons[i].c, 2, 1, file);
fread (&flags, 2, 1, file);
}
break;

case 0x4140:
fread (&howmany, sizeof (unsigned short), 1, file);

mapcoord = new mapcoord_class[howmany];

for (i=0; i<howmany; i++)
{
fread (&mapcoord[i].u, sizeof (float), 1, file);
fread (&mapcoord[i].v, sizeof (float), 1, file);
}
break;
}
}
fclose (file);
return (1);
}







It's a .3ds loader
It loads normally the vertexes but when it comes to polygons at run time it throws:

Unhandled exception at 0x00462840 in main.exe: 0xC0000005: Access violation reading location 0x00000004.

I cant find why and I dont understand why provided that it reads normally the vertexes,
it stalls when reading the polygons

The model class has private pointers:

vertex_class* vertex;
polygon_class* polygon;
mapcoord_class* mapcoord;

where:

class vertex_class
{
public:
float x,y,z;
};

class polygon_class
{
public:
unsigned int a,b,c;
};

class mapcoord_class
{
public:
float u, v;
};







thanks

[Edited by - Lord_Vader on September 9, 2006 2:43:53 PM]

Share this post


Link to post
Share on other sites
Yes, I have used fopen_s(another transfering mistake) look again


Quote:
Original post by ikslm
fread (&polygon[i].a, 2, 1, fileP);

sizeof(unsigned int) isn't 2 but 4 bytes.


So?
When I replace the pointer in the class:
polygon_class* polygons; with an array:

polygon_class polygons[20000];

everything runs perfectly
What do you suggest?

Share this post


Link to post
Share on other sites
Rather than having people guess at the problem here, why don't you step through your code with the debugger and see exactly whats happening? Set a breakpoint at your allocation for the polygons array, and see what your howmany variable is, and what your array looks like after the allocation.

Your 0xC0000005 error message means you're dereferencing a pointer that is pointing somewhere it shouldn't, and the easiest way to spot that is really with the debugger.

Share this post


Link to post
Share on other sites
This is the first thing I tried and I found thats something wrong with
the fread function when reading polygons data.It just doesnt read what it should(if I use the pointer, otherwise(with arrays) it works fine)...
The code isn't much complicated but I cant figure out what's wrong.So I asked
for help after a lot of searching

Share this post


Link to post
Share on other sites
You are reading 2 bytes per unsigned int per polygon. This is a total of 6 bytes. However, sizeof(polygon_class) is 12. You don't see a problem with this?

Share this post


Link to post
Share on other sites
You have undoubtedly tromped the heap somewhere. The code you posted is insufficient for me to tell where exactly the problem is. Either post a complete minimal example or replace all your raw pointer usage with SC++L constructs and recompile and debug with a checked SC++L implementation.

Σnigma

Share this post


Link to post
Share on other sites
Stop calling fread.

Replace calls to fread with calls to typed_fread

template<typename T>
size_t typed_fread( T* read_data, int count, FILE* file) {
return fread( read_data, sizeof(T), count, file);
}


Usage example:

// use the type of numofP to figure out what to read:
typed_fread(&numofP, 1, l_file);

or:

// Read into numofP. If numofP isn't an unsigned short, fail to compile:
typed_fread<unsigned short>(&numofP, 1, l_file);


In effect, "typed_fread" simply figures out the type of the variable you are reading for you.

Writing a typed_fwrite via the same syntax gets you the same advantage.

You are probably misaligning the size of the structures you are writing to with the amount of data you are reading.

[Edited by - NotAYakk on September 10, 2006 12:08:48 AM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Lord_Vader
So?
When I replace the pointer in the class:
polygon_class* polygons; with an array:

polygon_class polygons[20000];

The problem may be this: when you do the latter, the mem for polygons-array happens to get allocated from a place which happens to have zeroed the memory (this is not just pointless speculation; If you have a Model object as a global variable, this is certainly the case).

Now when you read only 2 bytes to a 4-byte integer: "fread (&polygons[i].a, 2, 1, file);" the integer may end up having the data XXXX0000 (hex), assuming the mem was initially zero. But if you do dynamic allocation, the mem isn't zeroed and the variable will be XXXX???? where ???? is some random 16-bit number. Later when you access the indices by doing something like vertex[polygons[i].a] the index will be a huge number 385496394 instead of 12 like you meant, and cause an access violation.

Solution: Set polygons[i].a = 0 (for all a,b,c of course) before reading only 2 bytes.

Share this post


Link to post
Share on other sites
Finally resolved.
Thanks all of you guys and especially:
Deyja
ikslm
NotAYakk
and the
Anonymous Poster

The problem was twofold:
1)It was a matter of size :) as the above said
2)One of the models I was loading had not texture coordinates so the coordinates
were missing from the file and the mapcoord pointer remained NULL(from the constructor) Result:acces violation when I was trying to display the model.

and by the way:

Quote:
Original post by Enigma
You have undoubtedly tromped the heap somewhere. The code you posted is insufficient for me to tell where exactly the problem is. Either post a complete minimal example or replace all your raw pointer usage with SC++L constructs and recompile and debug with a checked SC++L implementation.

Σnigma


Can you tell me what is SC++L?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this