in school the teacher told me that when the call to a function reaches an end everything declared inside the function's block will be erased.
That is a misleading characterization. If your instructor used that specific wording then they did you a disservice. It is not altogether wrong, though, depending on how one interprets it.
What the language specification says is that the lifetime of an object declared, without a storage-class specifier, inside a block (such as the block serving as the function body in a function definition) ends when execution of the innermost containing block ends. You might characterize that as such objects being "erased" in the sense of erasure from existence, but not in the sense of having their contents cleared.
the output was 9999 which doesn't suit what I was taught.
Trying to be as charitable towards the instructor as possible, I do suggest considering that you may have misunderstood what they were trying to tell you.
In any event, attempting to access an object whose lifetime has ended produces undefined behavior. Moreover, when an object's lifetime ends, the values of any pointers to that object become indeterminate. This means that your program's output does not, indeed cannot, contradict what the language specification says about the situation, because the program output is undefined. Any output or none would be equally consistent with C language semantics. If we suppose that your instructor was trying to convey a characterization consistent with the specification, then they are not contradicted either.