New ones:
- API call fails, but doesn't SetLastError(), or sometimes even returns success, so you have no way to tell what went wrong. Or it returns failure when it actually succeeded, because the return value that indicates failure is a valid return value on success as well.
- "Invalid conversion from char* to unsigned char*" when passing to a function that doesn't do anything in which it would matter anyway.
- For some reason, one of the more common side effects of memory corruption seems to be that malloc() will return pointers to blocks of already-allocated memory. You get two buffers that are at the same location and spend hours trying to figure out why one changes when you change the other. Or, your program will just close with no error message or anything. Stack overflow does this too. Just why did they decide the default exception handler should work this way?
More to come as I remember/find them.
Somewhat related, ever try installing Visual Studio 6, and when it asks if you want to reboot, select no? Here's the message you get when you do so:
Still better than IE6 "lol let's just reboot without any warning" though.
[edit] Weird one:
if(this->Text) free(this->Text);
this->Text = malloc(1);causes memory corruption, but seemingly equivalent code:
char* NewStr;
NewStr = realloc(this->Text, 1);
if(!NewStr) return false;
this->Text = NewStr;doesn't appear to.

I suspect it's still there, somewhere, and this may not even have been the cause, but it's not breaking anymore. (Really, I'm more curious as to why I used the first method to begin with...)
[edit 2] Nah, should have known that was too easy.

Also, new one: you run the program several times in a row, doing the exact same thing every time. The procedure involves no timers, random numbers, etc, so the results should be the same every time. In
one instance, it does something different.
[hey more editing]
I've found what I suspect is the problem, and it's a fucking sneaky bastard. Basically, a class contains a pointer to some memory that's malloc()'d in the constructor and free()'d in the destructor. There's a function which returns one of these classes. By the looks of it, the compiler puts a copy of the class to be returned on the stack as the return value. In this case, however, I was discarding the return value, so the copy is immediately destroyed. When the copy gets destroyed, the destructor is called... see the problem? Since it's a copy it frees the buffer that the original is still using. That's my current theory, anyway...
____________________