Stupid Question 119: Do we have pointers in C#?
Pointers are hard for the garbage collector to handle
You might have noticed that I pointed out (pun intended) in the last question (what are pointers?)that we do. Besides references being pointers we have also something we refer to as *just* pointers, the true pointers in C#. Pointers point and references reference- and the GarbageCollector can manage the latter but not the first.
How I know? I try to make it to all Robert C. Martins sessions at conferences. And during each session he asks the crowd : “Do we have pointers in C#?”. Usually only a few say yes, now that you know- make sure to answer right. I of course made sure to learn a little bit about pointers after the sessions(s), as the importance of understanding them was a recurrent theme .
So let’s forget about references and talk about pointers instead. Since they point to a specific place in memory, they pose a problem to the GarbageCollector. The GC won’t know what resides at that address, which makes it pretty hard- well actually impossible- to manage the life of the object.
Pointers in C# are limited, and not really recommended to use- but they do seem to have some usage,- since I haven’t used them I don’t feel like the right person to talk about the usage scenarios, but there is an interesting discussion about the usage of pointers in C# here for the curious. To sum it up, some usage scenarios mentioned are: (from MSDN)
Dealing with existing structures on disk
Advanced COM or Platform Invoke scenarios that involve structures with pointers in them
Performance-critical code
When you use pointers in C# you are required to use a keyword, unsafe. This keyword can be used in the type or member declaration. Pointers do not inherit from object, and lack therefore that conversation ability. For the same reason they can only be of basic types, such as: int, uint, long, ulong, char, float, double, decimal, bool etc. You get the point. ;)
Declaring pointers in C# :
Valid:
int* p1, p2, p3;
Invalid:
int *p1, *p2, *p3;
Comments
Not sure I like the idea of pointers in a language that doesn't let you deallocate that memory. Hated having to get my head around pointers when I started with C++ and then Objective-C; and having to remember to remove them when they were done with. Interesting though that C# has them, with a garbage collector. I've always thought of them as the *programming languages* way of telling you to think about what you're instantiating / assigning and do he garbage collection yourself. David
Garbage collectors are fun. I enjoy this (rather long) thesis on one of the first real-time garbage collectors: Scalable Real-time Parallel Garbage Collection for Symmetric Multiprocessors. It does a great job at introducing the entire concept through examples and explanations of early, naive garbage collection algorithms. (Many seminal theses are great for learning concepts... you get basic introductory passages and then immediately the expert state-of-the-art.) My "stupid" question answered: "Can we have garbage collection and use pointers?" Yes. Languages that use pointers openly and without regret can still use garbage collection. You could build a collector for C or C++ (and people have, naturally). If you do not imply that pointers should be wrapped and abstracted (system managed), these garbage collectors must be what are called conservative collectors. So, let's back up. Pointers are just integers, right? They contain numbers that tell you how far from the beginning of memory some value is stored. So, from the perspective of a garbage collector, it just sees a bunch of numbers. It can't actually know which is a pointer and which is an integer. Therefore, in a conservative collector, the collector scans all of a program's memory to discover if objects are still referenced. If it ever finds a number that matches an object's location in memory, it doesn't take any chances and marks it as being referenced. This occurs even when you simply have an integer written to a variable that happens to be the same value as the location of an object. At the end, if an object isn't referenced, it is destroyed. As you can see, it will free objects, however, by coincidence, it may not free an object even if it is not referenced directly. However, it won't leak memory, and it is still eventually correct-- it just won't free as much memory as it could per collect. Hence, conservative. However, if you take C++ for example and you tell people using pointers is unsafe, and you wrap memory and object allocation in your own GC functions such that you tag all object allocations so the GC can find them... *gasps for breath* you've essentially disallowed pointers and only allow references (actually... that's a big win! yay!), you can do non-conservative GC. But... you've invented a 'managed' environment. Now you basically have Java/C#/D. :) Loving the articles thus far. Will have to point students at them. :)
Last modified on 2013-01-03