The code shown will result in a memory leak. C++ does not have garbage collection unless you explicitly use a specialized framework to provide it.
The reason for this has to do with the way memory is managed in C/C++. For a local variable, like your example, memory for the object is requested directly from the operating system (malloc) and then the pointer to the object exists on the stack. Because C/C++ can do arbitrarily complex pointer arithmetic, the compiler has no way of knowing whether there exists some other pointer somewhere to the object, so it cannot reclaim the memory when function f() ends.
In order to prevent the leak automatically, the memory would have to be allocated out of a managed heap, and every reference into this heap would have to be carefully tracked to determine when a given object no longer was being used. You would have to give up C's ability to do pointer arithmatic in order to get this capability.
For example, let's say the compiler could magically figure out that all normal references to obj were defunct and deleted the object (released the memory). What if you had some insanely complicated RUNTIME DEPENDENT expression like void* ptr = (&&&&(&&&*obj)/2++ - currenttime() - 567 + 3^2 % 52) etc; How would the compiler know whether this ptr pointed to obj or not? There is no way to know. This is why there is no garbage collection. You can either have garbage collection OR complex runtime pointer arithmetic, not both.