Does this mean that an existing closure might refer to a non-local
variable that has already been de-allocated?
Yes. Extending an object's life-time which was allocated on the stack beyond the execution of the outer function seems to be somewhere between unreasonable and impossible. Also, the compiler won't try to check whether such an extension is needed and magically allocate the object on the heap or something like this. As a programmer you have to be explicit about what is supposed to happen with respect to allocation. If you want to use the free store (aka heap), use the free store. There is nothing magical going on with lambdas. If you make your closure object store the address of some other object that used to live on the stack and you try to access it after it's gone, the behaviour is undefined.
any special care / best practice that one has to follow when using
captured non-local variables inside a C++ closure?
Just make sure that your lambda does not capture by reference if the lambda object (or a copy of it) outlives the scope it (or the original) was created in. For example, using a lambda which captures by reference as argument to some of the algorithms you find in the algorithm header is perfectly fine.