The terminology is really confusing. g_source_destroy() removes the source from the main context. That name was a mistake. It won’t actually destroy the source on its own. But removing it from the main context may have the side effect of destroying it: semantically, you can think of it as the main context dropping its ref on the source, so if there are no other references remaining then it will be destroyed. But when you call this function yourself, you would usually have your own ref, so that ordinarily would not happen. A typical pattern would be: you call g_source_destroy(), then you possibly call g_source_unref() if you are done with it.
g_source_remove() just removes the GSource from the default main context using g_source_destroy(). But in this case, you probably don’t have your own ref, because it accepts an integer ID rather than a GSource object, so this would indeed usually destroy the source. But you can prevent that by keeping a ref.
The scenario you’re describing is probably a mistake. You don’t generally want to pair g_source_new() with g_source_remove(). You technically can, by using g_source_get_id() and passing it to g_source_remove(), but that’s really confusing. If you created the GSource using g_source_new(), then you would normally call g_source_destroy() and g_source_unref() instead of using g_source_remove().
g_source_remove() is normally paired with g_idle_add() or g_timeout_add() because those functions return a source ID, and g_source_remove() also takes a source ID. Those work well for simple cases, allowing you to create and destroy the source without ever using a GSource object. Whereas if you have a GSource, it’s normally better to use it and ignore the simple APIs that only take the source ID. I recommend you pick one set of APIs or the other. The APIs that operate on GSource objects give you more control and are necessary when you need anything other than the default main context. But the APIs that operate on integers are simpler and should be preferred when you can use them. See the main context tutorial to learn more.
“This does not unref the GSource: if you still hold a reference, use g_source_unref() to drop it.”
This implies, as you say, that the object is not unallocated.
Even if I use g_source_ref( ptrSource ) (to ensure the count doesn’t go to 0), and then g_source_delete( ptrSource ), I still get an error when I try to reattach with g_source_attach( ptrSource, NULL )