I prepare some little code snippet hereunder that represent my real world buged code.
byte count = 100;
byte* pointer = &count;
(*(ushort*)pointer) = (ushort)byte.MaxValue;
I found error in third row and fix it. *pointer = byte.MaxValue;
But I dont understand exactly why fault code sometimes run without error and sometimes failed with error:
malloc.c:2379: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
I see that instruction (*(ushort*)pointer) = (ushort)byte.MaxValue;
write two bytes in memory and second memory cell here may be used for other variables of current process or other processes.
Why sometimes error does not throw?
May be it run normally if second byte is "free"?
Or may be it throws only if second byte is owned by other process and is refers to other address space?
(*(ushort*)pointer) = (ushort)byte.MaxValue;
attempts to write 2 bytes via a pointer which actually points to 1 bytes.
The result is undefined behavior.
The example here for undefined behavior (under 23.5 Pointer conversions, 23.5.1 General), is showing a similar case:
unsafe static void M()
{
char c = 'A';
char* pc = &c;
void* pv = pc;
int* pi = (int*)pv; // pretend a 16-bit char is a 32-bit int
int i = *pi; // read 32-bit int; undefined
*pi = 123456; // write 32-bit int; undefined
}
In cases of undefined behavior [almost] anything can happen, including (but not necessarily) getting an error. The program might also seem to work as expected, but you should not count on it.
Regarding:
Or may be it throws only if second byte is owned by other process and is refers to other address space?
Each process has its own address space (on Windows see: Virtual Address Space) and a process cannot access the address space of another process like that.
So this is not relevant on your case (there are special Win32 apis for accessing a diffrent address space in certain cases - e.g. WriteProcessMemory, but it is not something you can trivially do like in your posted code).