There are a lot of good answers here. But this is definitely undefined behavior. Some people claim that undefined behavior means that purple dragons can fly from your computer or something like that ... maybe there’s some story behind this outrageous statement that I’m missing, but I promise you that purple dragons will not appear regardless of undefined behavior.
First of all, let me mention that if there is no MMU in a system without virtual memory, your program will have direct access to all the memory in the system, regardless of its address. In such a system, malloc() is just a guy who helps you cut out bits of memory in an orderly manner; the system cannot force you to use only the addresses that malloc() gave you. In a system with virtual memory, the situation is slightly different ... well, very different. But in your program, any code in your program can access any part of the virtual address space displayed through the MMU in real physical memory. It doesn’t matter if you had an address from malloc () or you called rand () and accidentally got an address that falls into the display area of your program; if it is displayed and not marked only by performance, you can read it. And if it is not read-only, you can also write it. Yes. Even if you did not receive it from malloc() .
Consider the possibilities for malloc(0) undefined behavior:
OK, that’s quite simple. Actually, the physical address is 0x00000000 on most computers and even the virtual address is 0x00000000 in all processes, but the OS does not intentionally map memory to this address so that it can catch pointer null references. There's a whole page (usually 4 KB) that just never appears on the map, and maybe even a lot more than 4 KB. Therefore, if you try to read or write a null pointer, even with an offset from it, you will hit these pages of virtual memory that are not even displayed, and the MMU will throw an exception (hardware exception or interrupt) that the OS catches and declares SIGSEGV (on Linux / Unix) or illegal access (on Windows).
malloc(0) returns a valid address in the previously unallocated memory of the smallest allocated element.
With this, you actually get the real part of the memory, which you can legally call your own, of a certain size, which you do not know. You really don't have to write anything (and probably don't read) because you don’t know how big it is, and in this case you don’t know if this is a specific case that you are experiencing (see the following cases). If so, the memory block you received is almost guaranteed to be at least 4 bytes and probably 8 bytes, or possibly even more; it all depends on the size of the minimum allowable implementation unit.
malloc(0) intentionally returns the address of an unsealed non-NULL memory page.
This is probably a good option to implement, as it will allow you or the system to track and connect the malloc () calls with their corresponding free () calls, but in essence it is the same as returning NULL. If you try to access (read / write) using this pointer, you will crash (SEGV or illegal access).
malloc(0) returns the address on another memory card that can be used by "someone else."
I find it unlikely that a commercially available system will use this route, since it serves to simply hide errors, rather than display them as soon as possible. But if that is the case, malloc () will return a pointer somewhere to non-owning memory. If so, of course, you can write whatever you want, but you will corrupt another code memory, although it will be memory in your program process, so you can be sure that you will at least not stomp in another program memory. (I heard someone getting ready to say: “But this is UB, so technically he could die on some other program memory. Yes, in some environments, such as an embedded system, this is correct. A commercial OS would allow one process accessing another process memory is as simple as calling malloc (0), but in fact you simply cannot move from one process to another process memory without going through the OS to do it for you.) Anyway back to reality ... This is where "undefined behavior" really works: if in If you write “someone else's memory” (in your own program process), you will change the behavior of your program in directions that are difficult to predict. Knowing the structure of your program and where everything is laid out in memory, it is completely predictable. But from one system to another, things will be laid out in memory (appearing in different places in the memory), so the effect on one system will not necessarily be the same as the effect on another system or on the same system at another time.
- And finally ... No, it is. Indeed, indeed, only those four possibilities. You can argue that for the subgrid points of the special case for the last two of the above, but the end result will be the same.