So finally after a little waking up i fixed my write to a file in raw binary problem. Now I am trying to load the same data from the file i created. Here is the code I came up with.

#include <fstream>
#include ".\vertexs.h"

using namespace std;

int LoadVerts(char *s_fName, OURCUSTOMVERTEX *p_Verts, short *p_Indices)
{
	long i_CountVerts;
	long i_CountInds;

	unsigned char buffer[sizeof(OURCUSTOMVERTEX)];

	basic_ifstream<unsigned char> f_DataFile;

	f_DataFile.open(s_fName, std::ios_base::in | std::ios_base::binary);

		f_DataFile.get(buffer, sizeof(unsigned long));
		memcpy_s(&i_CountVerts, sizeof(unsigned long), &buffer, sizeof(unsigned long));
		f_DataFile.get(buffer, sizeof(unsigned long));
		memcpy_s(&i_CountInds, sizeof(unsigned long), &buffer, sizeof(unsigned long));

		OURCUSTOMVERTEX *p_temp_Verts = new OURCUSTOMVERTEX[i_CountVerts];
		short *p_temp_Indices = new short[i_CountInds];

		for (int temp = 0; temp < i_CountVerts; temp++)
		{
			f_DataFile.get(buffer, sizeof(OURCUSTOMVERTEX));
			memcpy(&p_temp_Verts[temp], &buffer, sizeof(OURCUSTOMVERTEX));
		}

		for (int temp2 = 0; temp2 < i_CountInds; temp2++)
		{
			f_DataFile.get(buffer, sizeof(short));
			memcpy(&p_Indices[temp2], &buffer, sizeof(short));
		}
	f_DataFile.close();

	delete [] p_Verts;
	p_Verts = p_temp_Verts;
	delete [] p_Indices;
	p_Indices = p_temp_Indices;

	return 0;
}

The struct OURCUSTOMVERTEX is defined in the vertexs.h header file and contains 3 floats (x, y, z) and a unsigned long (color). When I build it no errors are returned at all, not even so much as a warning. But when I run this a system error as follows occurs:

Unhandled exception at 0x7c9377a2 in saveverts.exe: 0xC0000005: Access violation writing location 0x00030ffc.

Through a little breaking i found that the problem is coming in at the following portion of code:

for (int temp2 = 0; temp2 < i_CountInds; temp2++)
		{
			f_DataFile.get(buffer, sizeof(short));
			memcpy(&p_Indices[temp2], &buffer, sizeof(short));
		}

After stepping through the function, I found that the problem is originating here:

f_DataFile.get(buffer, sizeof(long));
		memcpy_s(&i_CountInds, sizeof(long), &buffer, sizeof(long));

At this point with my sample run the buffer should read 09 00 00 00 ... as the long stored in the file by the save routine stores an unsigned long with value 9, which is what is being read here. Instead the buffer reads 00 09 00 00, which is 900 hex, which is 2304 decimal. here inlays the problem, i believe. In any event, from my perspective this is the root of the problem, and unfortunately I am unable to troubleshoot it further on my own and must ask for help.

Following is the SaveVerts routine, in hopes that it will help:

int SaveVerts(char *s_fName, OURCUSTOMVERTEX *p_Verts, short *p_Indices, long i_CountVerts, long i_CountInds)
{
	unsigned char buffer[sizeof(OURCUSTOMVERTEX)];

	basic_ofstream<unsigned char> f_DataFile;

	f_DataFile.open(s_fName, std::ios_base::out | std::ios_base::binary);

		memcpy(&buffer, &i_CountVerts, sizeof(unsigned long));
		f_DataFile.write(buffer, sizeof(unsigned long));
		memcpy(&buffer, &i_CountInds, sizeof(unsigned long));
		f_DataFile.write(buffer, sizeof(unsigned long));

		for (int temp = 0; temp < i_CountVerts; temp++)
		{
			memcpy(&buffer, &p_Verts[temp], sizeof(OURCUSTOMVERTEX));
			f_DataFile.write(buffer, sizeof(OURCUSTOMVERTEX));
		}

		for (int temp2 = 0; temp2 < i_CountInds; temp2++)
		{
			memcpy(&buffer, &p_Indices[temp2], sizeof(short));
			f_DataFile.write(buffer, sizeof(short));
		}
	f_DataFile.close();

	return 0;
}

And finally this is the section of code in assembly (for all the ASM gurus out there) once the program crash and debug pops:

7C93779C  mov         edi,edi 
7C93779E  push        ebp  
7C93779F  mov         ebp,esp 
7C9377A1  push        ecx  
7C9377A2  push        ecx                        <**************problem line
7C9377A3  push        edi  
7C9377A4  mov         edi,7C97C320h 
7C9377A9  cmp         dword ptr ds:[7C97C320h],edi 
7C9377AF  jne         7C942DA0 
7C9377B5  xor         al,al 
7C9377B7  pop         edi  
7C9377B8  leave            
7C9377B9  ret         8

Thanks in advance for any insights.

Recommended Answers

All 7 Replies

The assembly line only points to where the IP was when the error was identified. (So it doesn't help.)

In any case, the problem is that unsigned char buffer[ n ]; creates a variable (buffer) which is, by itself, a pointer to a list of bytes. The number of bytes in the list is known to the compiler, but otherwise the array definition is just like saying:
1. reserve n bytes on the stack
2. create a variable unsigned char *buffer; 3. let buffer point to the first byte just reserved on the stack

Hence, the problem occurs when you say: memcpy_s(&i_CountInds, sizeof(long), [B]&buffer[/B], sizeof(long)); The types of the desired parameters are:
pointer to bytes, int, pointer to bytes, int.

The types of the arguments you give it are:
pointer to bytes, int, pointer to pointer, int.

So, the first time you read something you are changing the address in 'buffer' to point to some other, random position in memory. The next time you try to access the buffer you get an access violation --meaning that you tried to access memory that doesn't belong to you.

Remember, buffer by itself is a pointer. You can dereference it with *buffer or buffer[ 0 ] but without the * or [] it is just another pointer variable.

So, to fix your code, use memcpy_s(&i_CountInds, sizeof(long), [B]buffer[/B], sizeof(long)); Hope this helps.

While your explaination made perfect sense, it did not solve the problem. I made what should have been the required change and still get:

Unhandled exception at 0x7c9377d5 in saveverts.exe: 0xC0000005: Access violation writing location 0x00030ffc.

You are very sharp to catch this error... and I am slow for not. Though this was a problem... it is not THE problem. Further assistance would be appriciated.

You changed every instance of &buffer to buffer in both of the routines posted above?

If you have, I don't know where the problem is. My quick glance says they look alright to me. Unless you are reading or writing too many bytes for your buffer or integer types somewhere...

Does your custom vertex structure have any pointers in it?

Yes i changed them all in both functions.

As far as writing and reading too many bytes, i am writing and reading the exact same amount because i structured the LoadVerts routine from the SaveVerts routine with an exact copy and slight modification. Additionally after each of my runs, i am checking the chris. raw file against the output i should have based on my knowledge of how raw data is stored in files. They come out identical.

My struct is as follows and contains no pointers:

struct OURCUSTOMVERTEX
{
	float x, y, z;
	unsigned long color;
};

Can you see why this is frustrating me so?

Maybe you are just paying the price for using ifstream.get()? Is there a byte with the value 10 in your data file?

(You should be using ifstream.read().)

Let me know if that fixes it... (ATM I don't think it will...)

I am an IDIOT!

Okay just to make myself look retarded.... i will explain what happened.

Review the original code for LoadVerts.

Look near the bottom at this line:

memcpy(&p_Indices[temp2], buffer, sizeof(short));

The problem here is that the array that needs to be written to is p_temp_Indices (declared in this function) and then copied to the original array. Just goes to show that something small can cause a cog and stump a few.....

WOW! I should be more careful..... LOL!

Heh heh heh... I do stuff like that all the time... :twisted:

Please fix those get()s to read()s though...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.