POV-Ray : Newsgroups : povray.off-topic : C++ classes and file i/o : Re: C++ classes and file i/o Server Time
9 Oct 2024 05:24:08 EDT (-0400)
  Re: C++ classes and file i/o  
From: stbenge
Date: 13 Apr 2009 23:19:12
Message: <49e400b0@news.povray.org>
Darren New wrote:
> stbenge wrote:
>> as you suggested. I found out that by not explicitly assigning "val" 
>> (or tempFx, tempFy) an initial value, it was picking up nonsense and 
>> carrying it through as it read through the stream.
> 
> That doesn't make a whole lot of sense. fread() should be overwriting 
> the value.

Maybe I'm just working with a different kind of C++. I'm using a Mingw 
compiler. Can the standards be that different? fread() only returns the 
correct values when I clear the &xyz read variable to 0 first. I only 
need to do this once, though.

> You might want to check the return value from fread to make 
> sure you're getting what you think you're getting.

Ah, I made sure to do this as well. I made the first four map entries 0, 
1, 255 and 254. I printed this out to the console. This let me see what 
to do about the problem. When I fixed it, I saw those numbers. My 
program loaded and displayed the field correctly. Everything is perfect 
now, I can change levels at a whim with the arrow keys. Should I still 
be worried? Maybe I should create one or two extra Fields and display 
them, just to be sure?

> Plus, using 
> sizeof(int) is probably a better idea than "2".  If it's really 2 and 
> not sizeof(int) in your data file, then you ought to be reading 2 
> unsigned chars and doing the math to turn them into an integer lest you 
> get endian problems. Remember that &xyz doesn't necessarily point to the 
> low byte of the integer.
> 
> I.e., it would be better to do something like
>   unsigned char buf[2];
>   if (2 != fread(buf, 2, 1, fieldFile)) {
>     printf("Whoops!");
>     exit(1);
>   }
>   val = buf[0] + 256 * buf[1];
>   /* That only works for unsigned integers, btw */

I tried this, but with no success. I ended up with a screen full of the 
same tile. I think it is because I did not create the binary file in 
this manner. I'll look this all over again later, because I would like 
to do things in a safer manner.

> If you have four-byte integers, I wouldn't bet the way you've written it 
> works correctly. Especially not for signed values.

They are four-byte integers, and this may be part of the previous 
problem. This seems like the kind of issue which might bite me in the 
@ss later if I don't follow standard procedure.

>> I do not know why it would act this way inside a class member but not 
>> in other scenarios, but I suspect it has to do with how C++ allocates 
>> memory.
> 
> Well, data of global lifetime is specified as being initialized to 0 
> unless otherwise initialized.
>
> It could just be whatever random crap was 
> in your RAM, if both classes and variables were stack allocated.

This sounds like a reasonable explanation. I could attempt to prove that 
theory by making some code changes and see if that alters the nonsense 
value I was getting...

>> I may need to use these values another time, so I left that 
>> functionality in the binary format.
> 
> Ok. The better thing to do here would be to check that tempFx and tempFy 
> match fieldWidth and fieldHeight, if it's your intention that they 
> always match. Then the reader knows what you're talking about, plus you 
> get a chance to blow up if you later feed it the wrong data file.

This sounds like good coding practice. I don't ever plan to feed it the 
wrong files, but if I accidentally do, then at least I can crash the 
program gracefully ;)

Sam


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.