C++ Gurus, Can You Explain This?
<div class="IPBDescription">really, what am I missing about this...</div> So I was working on this program, which was crashing when I tried to read from a particular array, lets call it TM. Heres what the call looked like:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
unsigned char *TM;
...
TM = new unsigned char[size];
...
if(fread(&TM, sizeof(unsigned char), size, pFile) != size)
{
//do failure stuff
}
...
unsigned char x = TM[index]
<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
And it would crash on that last line. It was easy to fix, once I found the error (&TM should just be TM, boy did I smack myself when I noticed it), which took a while since there is obviously more code than I'm showing here and everything regarding access to TM worked until I tried to read from it. What I don't get is why the fread succeded even though I gave it an invalid pointer. Any ideas?
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
unsigned char *TM;
...
TM = new unsigned char[size];
...
if(fread(&TM, sizeof(unsigned char), size, pFile) != size)
{
//do failure stuff
}
...
unsigned char x = TM[index]
<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
And it would crash on that last line. It was easy to fix, once I found the error (&TM should just be TM, boy did I smack myself when I noticed it), which took a while since there is obviously more code than I'm showing here and everything regarding access to TM worked until I tried to read from it. What I don't get is why the fread succeded even though I gave it an invalid pointer. Any ideas?

Comments
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
unsigned char *p;
*p = 0;
fwrite(p, sizeof(unsigned char), size, pFile);<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
size in this case is a fairly large number, when the resulting file is examined with a hex editor, one can clearly see that it did not generate all 0x00s as intended. Any ideas?
TM is a pointer, so the value it contains is a memory address. Since a pointer is a variable, it's also stored somewhere, and therefore has an address itself. <span style='font-family:Courier'>&TM</span> is the address of the pointer. That's still a memory address. So you're overwriting your pointer, and because you're writing more than pointer-sized data you'll start corrupting whatever's after that pointer until you get a segmentation violation, which is your OS protecting other processes from your stuff-ups, and the reason why it crashes.
About your second question:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->fwrite(p, sizeof(unsigned char), size, pFile);<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
size is not how many times to write. It's how many elements to write. Think about that for a second.
*p == 0 == p[0], right? What does p[1] equal? God knows. Whatever values were left in the memory from last time it was written to. So if you're writing all the way up to, say, p[256] then you're writing one zero (which you put there, in *p = 0) and then 255 god-knows-whats.
size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream );
The size of <i>buffer</i> must be (<i>size</i> * <i>count</i>) bytes. For both functions.
In answer to your first question, fread will simply write to whatever happens to be at <i>buffer</i>. C makes no distinction between valid and invalid addresses. So, in your <i>&TM</i> case, fread will trash whatever is at <i>&TM</i>. The end result is that fread will either continue obliviously, or crash your program. Or your program could crash in the future because the memory fread has overwritten has now been read by something further in the program. Evil.
The second question, refer to my original point about the size of <i>buffer</i>. Now look at the size of your buffer <i>p</i>. Some code for writing 0s to <i>stream</i>:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
unsigned char* p = new unsigned char[size];
memset(p, 0, size);
fwrite(p, sizeof(unsigned char), size, pFile);
<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
A quick point about your first code:
<!--c1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
if(fread(&TM, sizeof(unsigned char), size, pFile) != size)
<!--c2--></td></tr></table><div class='postcolor'><!--ec2-->
fread can return less than size when it reaches EOF. In this case, use feof or ferror to determine if you have a file error, or that you've reached EOF.