Why Closures Are Hard
It's no accident that closures are more common in languages that include garbage collection than in those that don't. In a garbage-collected environment, the "upwards funarg problem" (where you pass a closure up the stack) is much easier to solve, because some of the code already frees memory that is no longer referenced.
In the counter example, the c variable and the closure would be moved from the stack to a garbage-collected allocation and would be freed automatically when the pointer to the closure was destroyed. In fact, most garbage-collected languages use a linked list of garbage-collected activation records, rather than a stack. Simula implemented objects as closures that returned a pointer to their own activation record. This action is impossible to do automatically in C, because it has no mechanism for tracking where pointers are. For example, you can store a pointer in an integer variable, perform some arithmetic on it, and then restore it later. Unless you're willing to recompile all of your code, there's no way for the compiler to run some code automatically when all references to an object are destroyed.
Properly implementing closures in C requires some explicit memory management and a new calling convention that allows functions to be called with the hidden argument automatically inserted by the compiler. This isn't a particularly new idea, though, because both C++ and Objective-C pass a hidden pointer to the object when calling methods.