I have the following font object and when I declare some empty font objects in another object I get this seg fault. Do you see what I may be doing wrong with this and why it seg faults only when I create fonts that are unused? Other fonts that are declared and rendered don’t have the problem. The problem only happens when I add a Font object as part of a member that doesn’t get used at all. I would expect to be able to create an empty font object.
#ifndef FONT_H
#define FONT_H
#include <SDL2/SDL_ttf.h>
#include "Renderable.h"
namespace ley {
class Font : public Renderable {
private:
    std::string textMessage;
    SDL_Texture* Message;
    SDL_Rect Message_rect;
    TTF_Font* Classic;
    SDL_Color color;
protected:
public:
    Font();
    Font(int, int, int, int);
    ~Font();
    void init();
    Font& operator=(const ley::Font& other); //copy assignment
    Font operator()(Font& other); //copy constructor
    void updateMessage(std::string s); // TODO this should be setMessage instead of updateMessage.
    std::string getMessage();
    std::string* getMessagePtr();
    SDL_Texture* getTexturePtr();
    void preRender(SDL_Renderer* r);
    void render(SDL_Renderer * r, bool d);
    TTF_Font* getTTFFont();
    void setPos(SDL_Point p);
    std::pair<int, int> size();
    void setColor(SDL_Color c);
};
}
#endif
#include "Font.h"
ley::Font::Font()
: 
Message(nullptr), 
Classic(nullptr) {
    Message_rect.x = 0;
    Message_rect.y = 0;
    Message_rect.h = 0;
    Message_rect.w = 0;
    init();
}
ley::Font::Font(int x, int y, int w, int h)
:
Message(nullptr),
Classic(nullptr) {
    Message_rect.x = x;
    Message_rect.y = y;
    Message_rect.w = w;
    Message_rect.h = h;
    init();
}
void ley::Font::init() {
    if (TTF_Init() < 0) {
        SDL_Log("TTF_Init failed");
    }
    SDL_Log("Open font %s", textMessage.c_str());
    Classic = TTF_OpenFont("assets/fonts/MartianMono-Regular.ttf", 24);    
    if(!Classic) {
        printf("TTF_OpenFont: %s\n", TTF_GetError());
    }
    color = {255, 255, 255, 255};
}
ley::Font::~Font() {
    if(Message) {
        SDL_DestroyTexture(Message);
    }
    
    SDL_Log("Close Font %s , Inits, %d", textMessage.c_str(), TTF_WasInit());
    if(Classic) {
        TTF_CloseFont(Classic);
        Classic = nullptr;
    }
    TTF_Quit();
}
//copy assignment operator
/*
ley::Font& ley::Font::operator=(ley::Font other) {
    
    Message = nullptr;
    Message_rect.x = other.Message_rect.x;
    Message_rect.y = other.Message_rect.y;
    Message_rect.w = other.Message_rect.w;
    Message_rect.h = other.Message_rect.h;
    updateMessage("");
    return *this;
}
*/
ley::Font& ley::Font::operator=(const ley::Font& other) {
    if (this == &other) return *this; // Handle self-assignment
    // Free existing resources
    if (Message) {
        SDL_DestroyTexture(Message);
        Message = nullptr;
    }
    if (Classic) {
        TTF_CloseFont(Classic);
        Classic = nullptr;
    }
    // Copy the state
    Message_rect = other.Message_rect;
    color = other.color;
    textMessage = other.textMessage;
    // Reinitialize resources
    Classic = TTF_OpenFont("assets/fonts/MartianMono-Regular.ttf", 24);
    if (!Classic) {
        printf("TTF_OpenFont failed: %s\n", TTF_GetError());
    }
    return *this;
}
ley::Font ley::Font::operator()(ley::Font& other) {
    Message = nullptr;
    if (Classic) {
        TTF_CloseFont(Classic);
    }
    
    SDL_Log("Open font");
    Classic = TTF_OpenFont("assets/fonts/Montserrat-Regular.ttf", 24);
    if(!Classic) {
        printf("TTF_OpenFont: %s\n", TTF_GetError());
    }
    Message_rect.x = other.Message_rect.x;  //controls the rect's x coordinate
    Message_rect.y = other.Message_rect.y; // controls the rect's y coordinte
    Message_rect.w = other.Message_rect.w; // controls the width of the rect
    Message_rect.h = other.Message_rect.h; // controls the height of the rect
    return *this;
}
void ley::Font::setColor(SDL_Color c) {
    color = c;
}
void ley::Font::updateMessage(std::string s) {
    //Only update the texture if the message has changed.
    if(s != textMessage) {
        textMessage = s;
        //then invalidate the texture
        if(Message) {
            SDL_DestroyTexture(Message);
            Message = nullptr;
        }
    }
}
std::string ley::Font::getMessage() {
    return textMessage;
}
std::string* ley::Font::getMessagePtr() {
    return &textMessage;
}
SDL_Texture* ley::Font::getTexturePtr() {
    return Message;
}
void ley::Font::preRender(SDL_Renderer* r)
{
    if(!Message) {
        SDL_Surface* surfaceMessage;
        surfaceMessage = TTF_RenderUTF8_Solid(Classic, textMessage.c_str(), color);
        Message = SDL_CreateTextureFromSurface(r, surfaceMessage);
        SDL_FreeSurface(surfaceMessage);
        surfaceMessage = nullptr;
    }
}
void ley::Font::render(SDL_Renderer * r, bool d) {
    preRender(r);
    
    // TODO this query texture should probably go in the setpos method and be called only when the position changes.
    int w;
    int h;
    SDL_QueryTexture(Message,
                     NULL, NULL,
                     &w, &h);
    Message_rect.h = h;
    Message_rect.w = w;
    SDL_RenderCopy(r, Message, NULL, &Message_rect);
}
TTF_Font* ley::Font::getTTFFont() {
    return Classic;
}
void ley::Font::setPos(SDL_Point p) {
    Message_rect.x = p.x;
    Message_rect.y = p.y;
}
std::pair<int, int> ley::Font::size() {
    int width = -1;
    int height = -1;
    if(Classic) {
        TTF_SizeText(Classic, textMessage.c_str(), &width, &height);
    }
    return std::make_pair(width, height);
}