How come ap does point to a partially valid object?
ap doesn't point to a partially valid object. This is UB. The code works, because even though k goes out of scope, the memory is unchanged.
What happens here, is that when k goes out of scope, the memory offset for free stack memory (where the next stack object will be placed) is changed, so k (the memory where k "was") remains in free stack space. Placing another object on the stack (after the loop) will probably invalidate the memory at the address in ap.
UB means that anything could happen (in this case, "anything" means that the memory pointed to by ap, still points to the address of the A::p function.