I thought after function returns, the content of local variables will be deleted.
C has no such rule. It has no “delete” operation.
When an object is created, memory is reserved for it. This just means arrangements are made that some particular memory is available to store the value of the object and nothing else will use that memory for anything else. In typical C implementations, some memory on the hardware stack is used for automatic objects (the objects of variables defined inside functions that are not static or thread-local).
When the lifetime of the object ends, as when a function returns, that memory is no longer reserved.
That is all the C standard guarantees: That the memory is no longer reserved. It does not guarantee that the memory is erased, that the memory is cleared, or that the memory is immediately reused for another purpose. It is like checking out of a hotel room: The moment you check out, the hotel housekeeping staff might rush into the room and clean it up, or they might leave it while doing other work.
The C standard does not define the behavior when you use memory that is no longer reserved. Further, if you have a pointer to an object, the C standard does not define the behavior if you use the value of the pointer after the lifetime of the object ends.
When the C standard does not define the behavior, it imposes no requirements on how the program behaves. If the program leaves the data in memory and fetches its value when you try to use it, that conforms to the C standard. If the program overwrites the memory as the function is exiting and the value of the object is gone, that also conforms to the C standard. Generally, the C environment will not manage things for you; it is your job to write code that complies with the rules.