If you compile your program with the debug flags (-g) (oh, and use -O0 to make sure no optimizations are made), you might see more information that could be useful.
Obviously we can see that the crash is happening when your font is being deleted. With debug output, we might be able to see which line is being called at each point in the stack trace, which will help us narrow down what is happening.
Although now that I am looking at your main function, here's my educated guess at what is happening: you are calling deinit() before your font is getting destroyed.
You call init(), which initializes all of your subsystems for SDL, then you create your Window, Player, Font, and Text objects on the stack.
But then you call deinit(), which shuts down all the SDL functionality, and when your main function exits, it calls the destructors on your objects in reverse order of when they were created. The Text object has an uninteresting destructor, so it's fine, but then your Font object calls TTF_CloseFont(), yet you've already called TTF_Quit().
You should probably ensure that deinit() is called after your resources are finished using SDL functionality. The two ways to do it would be to enclose everything in main after init() and before deinit() in curly braces so that it has its own scope (my preference), or use pointers and make sure to delete the objects before calling deinit().
With the enclosing scope, you can guarantee that objects created within that scope, like your Font object, will get destroyed when that scope is exited automatically, and then your deinit() should be safe to use.
Let me know if this information helps!