The idea is to keep in mind that when you forward elements into a network, the output has a history of all the operations that were performed (to be able to compute gradients).
In your case, the features contained all the history of what happened during the cnn forward.
Then when you use these in the lstm, the output of the lstm contains the history of what happened in the lstm and what happened in the cnn. In some sense, the history of the lstm output contains the history of the features.
When you backpropagate, the whole history is traversed and gradients are computed for Variables that requires_grad and intermediary buffers are freed to reduce memory usage.
So if you use the features multiple times, this same history will be shared by multiple output of the lstm, and the first one, when backpropagating will traverse this history and free it. But the second one will try to traverse this common part of the history as well, but that is not possible because it has been freed already.
What the detach() function does, is to detach a Variable from its history. So backpropagating will stop at this Variable. When using this, the lstm outputs will not have a shared history hence no problem.
Does that make sense?