I think a source of much of the confusion is the stack in C++, where the programmer had much more implicit control. In C# to be honest, I don't really know why they even made the distinguishment. They should have probably ignored the concept completely and made it something only the compiler developers were really aware of. Worst case scenario, for those few edge cases where the developer needed to optimize for stack usage, it could have been exposed as an attribute. Actually, there is already the stackalloc method, so even this wouldn't be need.
Yes, this tripped me at first when moving from C++ (along with a few other memory related details) - the best thing for me (from a practical viewpoint) was to just forget about the hows and whys of memory in .net and trust the framework to take care of it all. I still get a twinge of, er, guilt maybe?, every now and then when tossing around a ton of instanced objects. Old habits, I suppose.
Not to say these things aren't important to know, and some of the wonderful replies here have filled in the rough spots of my understanding.