I am trying to comprehend the concept of how pointers know who they are pointing at |
hardware. ram is like a giant array of bytes, and each byte has a location.
eg ram[number] is what was put there. When you get a pointer, the OS assures you that its usable (clean, not in use by others) and you stuff your data there. The pointer itself is just an integer, sorta kinda the index into ram. (this is a simplification; but its more or less conceptually correct; I am not sure all machines can address by bytes or if they do it by pages & offsets or some funky low level thing, but from your code/ c++ viewpoint, what I said is good enough here).
Why can't we do this in C++? |
You can. You just need to do that manually, with the tools provided; its not automated probably for two reasons 1) raw pointer memory manipulation is avoided in all but the most performance critical code in modern c++ (we use c++ object containers like vector to do the bulk of this in most programs now) and 2) its pretty simple to do it yourself, we don't need more clutter to do things that are rarely done and when they are, are usually better hand-tuned than cookie cutter.
I don't understand why copying and moving this memory wouldn't create new pointers to go along with the copied memory and delete the old ones pointing at the old, fragmented memory we wanted to clean up.
|
well, you do it yourself.
1) create a new pointer variable destination and ask for memory for it. //your new pointers
2) copy the memory, probably with memcpy //the copy operation
3) delete the old pointers
C++ memory does not fragment 'naturally'. That is, a NEW statement gives you a block of memory and you can't fragment that. You can only fragment memory if you build a data structure that has multiple pointers, one for each chunk of memory, and that is a self inflicted problem that you chose in your design phase knowing that it would fragment.
linked lists, trees, and graphs can be written in a CLASSICAL style that fragments memory where each "NODE" has pointers to more nodes and they all get 'new' memory independent of each other. But you CAN write these data structures in a way to NOT do that; its just the classical school design that does this. Its very easy, using a vector, to avoid the fragmentation entirely. As a bonus, the vectorized list is going to serialize better because the "pointers" are no longer pointers but array index into a persistent offset so you can directly load and save without having extra code to reconstruct it. NOTHING IS FREE. If you used a vector to make a linked list object, it would have fewer page faults but it will still do the copy and move when it needs to grow in size and that is an expensive operation. It can be minimized, but it can't be totally avoided unless your data is static or has a maximum size etc.
arrays, vectors, pointer-blocks (new type[size]) are all non fragmented.
Memory fragmentation is a giant slowdown in high performance code and is a good thing to understand. C++ provides you the tools to deal with it for your program however you want, but that is hands-on unless you are satisfied with the way a container does it for you. Java ... I don't know what java does, but its sluggish when you get down and dirty with the memory management, it simply can't seem to keep up for that specific area. Its gotten to be a decently well performing language, but, ... not a lot of high end games are written in java. For a reason.