SQL error: (null)

SQL error: (null) - Что это значит? Программа на с++ с использованием gtk4. Ubuntu, g++ 17. После нескольких таких ошибок происходит Segmentation fault (core dumped). Ошибка в функции GetProduct. Помогите, пожалуйста

#include <iostream>
#include <sqlite3.h>
#include <string>
#include <map>
#include <vector>
#include <gtk/gtk.h>
#include <typeinfo>
#include <fstream>
using namespace std;

class MainDB
{
public:
    sqlite3 *db;
    MainDB()
    {
        if (sqlite3_open("main.db", &db))
        {
            cout << "Can't open database: " << sqlite3_errmsg(db) << endl;
        }
        else
        {
            sqlite3_enable_load_extension(db, 1);
            char *ErrMsg;
            string sql = "SELECT load_extension('./fileio.so')";
            sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
            cout << "Opened database successfully" << endl;
        }
    }
    ~MainDB()
    {
        sqlite3_enable_load_extension(db, 0);
        sqlite3_close(db);
    }
    void first_launch()
    {
        char *ErrMsg;
        const char *sql = "CREATE TABLE PRODUCT (id INTEGER PRIMARY KEY AUTOINCREMENT, photo BLOB, name TEXT,\
         materials TEXT, place_of_storage TEXT, count INTEGER, weight INTEGER, height INTEGER, width INTEGER,\
          cost_price INTEGER, price INTEGER)";
        sqlite3_exec(db, sql, callback, NULL, &ErrMsg);
        sql = "CREATE TABLE MATERIAL (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, price INTEGER,\
         count INTEGER, photo BLUB, supplier_id INTEGER)";
        sqlite3_exec(db, sql, callback, NULL, &ErrMsg);
        sql = "CREATE TABLE SUPPLIER (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, numbers TEXT,\
         URL TEXT, address TEXT, mail TEXT)";
        sqlite3_exec(db, sql, callback, NULL, &ErrMsg);
    }
    static int callback(void *unused, int count, char **data, char **columns) {
        return 0;
    }
    void AddProduct(string photo, string name, string materials, string place_of_storage,
                    int count, int weight, int height, int width, int cost_price, int price)
    {
        char *ErrMsg;
        string sql = "INSERT INTO PRODUCT (photo, name, materials, place_of_storage, count, weight, height, width, \
        cost_price, price) VALUES (readfile('" +
                     photo + "'), '" + name + "', '" + materials + "', '" +
                     place_of_storage + "', " + to_string(count) + ", " + to_string(weight) + ", " + to_string(height) + ", " + to_string(width) + ", " + to_string(cost_price) + ", " + to_string(price) + " );";
        sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
    }
    void RedProduct(int id, string name_of_field, string value)
    {
        char *ErrMsg;
        string sql = "UPDATE PRODUCT SET " + name_of_field + " = '" + value + "' WHERE id=" + to_string(id) + " ;";
        sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
    }
    void RedProduct(int id, string name_of_field, int value)
    {
        char *ErrMsg;
        string sql = "UPDATE PRODUCT SET " + name_of_field + " = " + to_string(value) + " WHERE id=" + to_string(id) + " ;";
        sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
    }
    void DelProduct(int id)
    {
        char *ErrMsg;
        string sql = "DELETE FROM PRODUCT WHERE id=" + to_string(id) + " ;";
        sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
    }
    void AddMaterial(string name, int price, int count, string photo, int supplier_id)
    {
        char *ErrMsg;
        string sql = "INSERT INTO MATERIAL (name, price, count, photo, supplier_id) VALUES ('" + name + "', " + to_string(price) + ", " + to_string(count) + ", readfile('" + photo + "'), " + to_string(supplier_id) + ");";
        sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
    }
    void RedMaterial(int id, string name_of_field, string value)
    {
        char *ErrMsg;
        string sql = "UPDATE MATERIAL SET " + name_of_field + " = '" + value + "' WHERE id=" + to_string(id) + " ;";
        sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
    }
    void RedMaterial(int id, string name_of_field, int value)
    {
        char *ErrMsg;
        string sql = "UPDATE MATERIAL SET " + name_of_field + " = " + to_string(value) + " WHERE id=" + to_string(id) + " ;";
        sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
    }
    void DelMaterial(int id)
    {
        char *ErrMsg;
        string sql = "DELETE FROM MATERIAL WHERE id=" + to_string(id) + " ;";
        sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
    }
    void AddSupplier(string name, string numbers, string URL, string address, string mail)
    {
        char *ErrMsg;
        string sql = "INSERT INTO SUPPLIER (name, numbers, URL, address, mail) VALUES ('" + name + "', '" + numbers + "', '" + URL + "', '" + address + "', '" + mail + "');";
        sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
    }
    void RedSupplier(int id, string name_of_field, string value)
    {
        char *ErrMsg;
        string sql = "UPDATE SUPPLIER SET " + name_of_field + " = '" + value + "' WHERE id=" + to_string(id) + " ;";
        sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
    }
    void RedSupplier(int id, string name_of_field, int value)
    {
        char *ErrMsg;
        string sql = "UPDATE MATERIAL SET " + name_of_field + " = " + to_string(value) + " WHERE id=" + to_string(id) + " ;";
        sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
    }
    void DelSupplier(int id)
    {
        char *ErrMsg;
        string sql = "DELETE FROM SUPPLIER WHERE id=" + to_string(id) + " ;";
        sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
    }
    map<int, string> GetProduct(int id){
        id += 1;
        cout << id << endl;
        map<int, string> m;
        char *ErrMsg;
        sqlite3_stmt *stmt;
        string sql = "SELECT * FROM PRODUCT WHERE id=" + to_string(id);
        int rc = sqlite3_prepare_v2(this->db, sql.c_str(), -1, &stmt, NULL);
        if (rc != SQLITE_OK){
            fprintf(stderr, "SQL error: %s\n", ErrMsg);
            cout << ErrMsg << endl;
            sqlite3_free(ErrMsg);
        }
        else{
            while ((rc = sqlite3_step(stmt) == SQLITE_ROW)){
                for (int i = 0; i < 11; i++){
                    if (i != 1)
                    {
                        string new_req = reinterpret_cast<const char *>(sqlite3_column_text(stmt, i));
                        m.insert(pair<int, string>(i, new_req));
                    }
                }
            }
        }
        return m;
    }
    string GetProductImg(int id)
    {
        char *ErrMsg;
        string sql = "SELECT writefile('img.jpg', photo) FROM PRODUCT WHERE id=" + to_string(id);
        sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
        return "./img.jpg";
    }
    map<int, string> GetMaterial(int id)
    {
        map<int, string> m;
        char *ErrMsg;
        sqlite3_stmt *stmt;
        string sql = "SELECT * FROM MATERIAL WHERE id=" + to_string(id);
        int rc = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, NULL);
        if (rc != SQLITE_OK)
        {
            fprintf(stderr, "SQL error: %s\n", ErrMsg);
            sqlite3_free(ErrMsg);
        }
        else
        {
            while ((rc = sqlite3_step(stmt) == SQLITE_ROW))
            {
                for (int i = 0; i < 6; i++)
                {
                    if (i != 4)
                    {
                        string new_req = reinterpret_cast<const char *>(sqlite3_column_text(stmt, i));
                        m.insert(pair<int, string>(i, new_req));
                    }
                }
                cout << endl;
            }
        }
        return m;
    }
    string GetMaterialImg(int id)
    {
        char *ErrMsg;
        string sql = "SELECT writefile('img.jpg', photo) FROM MATERIAL WHERE id=" + to_string(id);
        sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
        return "./img.jpg";
    }
    map<int, string> GetSupplier(int id)
    {

        map<int, string> m;
        char *ErrMsg;
        sqlite3_stmt *stmt;
        string sql = "SELECT * FROM SUPPLIER WHERE id=" + to_string(id);
        int rc = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, NULL);
        if (rc != SQLITE_OK)
        {
            fprintf(stderr, "SQL error: %s\n", ErrMsg);
            sqlite3_free(ErrMsg);
        }
        else
        {
            while ((rc = sqlite3_step(stmt) == SQLITE_ROW))
            {
                for (int i = 0; i < 6; i++)
                {
                    string new_req = reinterpret_cast<const char *>(sqlite3_column_text(stmt, i));
                    m.insert(pair<int, string>(i, new_req));
                }
                cout << endl;
            }
        }
        return m;
    }
    vector<map<int, string>> GetProducts()
    {
        vector<map<int, string>> v;
        map<int, string> m;
        char *ErrMsg;
        sqlite3_stmt *stmt;
        string sql = "SELECT * FROM PRODUCT";
        int rc = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, NULL);
        if (rc != SQLITE_OK)
        {
            fprintf(stderr, "SQL error: %s\n", ErrMsg);
            sqlite3_free(ErrMsg);
        }
        else
        {
            while ((rc = sqlite3_step(stmt) == SQLITE_ROW))
            {
                for (int i = 0; i < 11; i++)
                {
                    if (i != 1)
                    {
                        string new_req = reinterpret_cast<const char *>(sqlite3_column_text(stmt, i));
                        m.insert(pair<int, string>(i, new_req));
                    }
                }
                v.push_back(m);
                m.clear();
            }
        }
        return v;
    }
    vector<map<int, string>> GetMaterials()
    {
        vector<map<int, string>> v;
        map<int, string> m;
        char *ErrMsg;
        sqlite3_stmt *stmt;
        string sql = "SELECT * FROM MATERIAL";
        int rc = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, NULL);
        if (rc != SQLITE_OK)
        {
            fprintf(stderr, "SQL error: %s\n", ErrMsg);
            sqlite3_free(ErrMsg);
        }
        else
        {
            while ((rc = sqlite3_step(stmt) == SQLITE_ROW))
            {
                for (int i = 0; i < 6; i++)
                {
                    if (i != 4)
                    {
                        string new_req = reinterpret_cast<const char *>(sqlite3_column_text(stmt, i));
                        m.insert(pair<int, string>(i, new_req));
                    }
                }
                v.push_back(m);
                m.clear();
            }
        }
        return v;
    }
    vector<map<int, string>> GetSuppliers()
    {
        vector<map<int, string>> v;
        map<int, string> m;
        char *ErrMsg;
        sqlite3_stmt *stmt;
        string sql = "SELECT * FROM SUPPLIER";
        int rc = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, NULL);
        if (rc != SQLITE_OK)
        {
            fprintf(stderr, "SQL error: %s\n", ErrMsg);
            sqlite3_free(ErrMsg);
        }
        else
        {
            while ((rc = sqlite3_step(stmt) == SQLITE_ROW))
            {
                for (int i = 0; i < 6; i++)
                {
                    string new_req = reinterpret_cast<const char *>(sqlite3_column_text(stmt, i));
                    m.insert(pair<int, string>(i, new_req));
                }
                v.push_back(m);
                m.clear();
            }
        }
        return v;
    }
};

class Window
{
private:
    MainDB db;
    GtkWidget *window;
    GtkWidget *notebook;
    GtkWidget *boxes[3];
    GtkWidget *grids[3];
    GtkWidget *view_panels[3];

    typedef struct
    {
        GtkWidget *my_grid;
        int page;
        int n;
    } MyData;

public:
    std::string product_keys[11] = {"id", "Фото", "Наименование", "Материалы", "Место хранения",
                                    "Количество", "Ширина", "Высота", "Вес", "Цена товара", "Себестоимость"};
    std::string material_keys[6] = {"id", "Наименование", "Себестоимость", "Количество", "Фото", "Номер продавца (id)"};
    std::string supplier_keys[6] = {"id", "Наименование", "Номер телефона", "URL", "Адрес", "Почта"};
    Window(GtkApplication *app, gpointer user_data)
    {
        window = gtk_application_window_new(app);
        gtk_window_set_title(GTK_WINDOW(window), "Модная пчела");
        gtk_window_set_default_size(GTK_WINDOW(window), 1400, 500);

        this->settings();

        gtk_widget_show(window);
    }
    ~Window() {}
    void settings()
    {
        this->notebook = gtk_notebook_new();
        GtkWidget *scroll_wins[] = {gtk_scrolled_window_new(), gtk_scrolled_window_new(), gtk_scrolled_window_new()};
        this->boxes[0] = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
        gtk_box_set_homogeneous(GTK_BOX(this->boxes[0]), TRUE);
        this->boxes[1] = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
        gtk_box_set_homogeneous(GTK_BOX(this->boxes[1]), TRUE);
        this->boxes[2] = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
        gtk_box_set_homogeneous(GTK_BOX(this->boxes[2]), TRUE);

        this->grids[0] = gtk_grid_new();
        gtk_grid_set_column_homogeneous(GTK_GRID(this->grids[0]), TRUE);
        this->grids[1] = gtk_grid_new();
        gtk_grid_set_column_homogeneous(GTK_GRID(this->grids[1]), TRUE);
        this->grids[2] = gtk_grid_new();
        gtk_grid_set_column_homogeneous(GTK_GRID(this->grids[2]), TRUE);

        gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scroll_wins[0]), this->grids[0]);
        gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scroll_wins[1]), this->grids[1]);
        gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scroll_wins[2]), this->grids[2]);

        gtk_window_set_child(GTK_WINDOW(this->window), this->notebook);
        gtk_notebook_append_page(GTK_NOTEBOOK(this->notebook), boxes[0], gtk_label_new_with_mnemonic("Продукты"));
        gtk_notebook_append_page(GTK_NOTEBOOK(this->notebook), boxes[1], gtk_label_new_with_mnemonic("Материалы"));
        gtk_notebook_append_page(GTK_NOTEBOOK(this->notebook), boxes[2], gtk_label_new_with_mnemonic("Поставщики"));
        gtk_box_append(GTK_BOX(this->boxes[0]), scroll_wins[0]);
        gtk_box_append(GTK_BOX(this->boxes[1]), scroll_wins[1]);
        gtk_box_append(GTK_BOX(this->boxes[2]), scroll_wins[2]);
        // view panels
        this->view_panels[0] = gtk_grid_new();
        this->view_panels[1] = gtk_grid_new();
        this->view_panels[2] = gtk_grid_new();
        gtk_box_append(GTK_BOX(this->boxes[0]), this->view_panels[0]);
        gtk_box_append(GTK_BOX(this->boxes[1]), this->view_panels[1]);
        gtk_box_append(GTK_BOX(this->boxes[2]), this->view_panels[2]);
        gtk_grid_set_column_homogeneous(GTK_GRID(this->view_panels[0]), TRUE);
        gtk_grid_set_column_homogeneous(GTK_GRID(this->view_panels[1]), TRUE);
        gtk_grid_set_column_homogeneous(GTK_GRID(this->view_panels[2]), TRUE);
        //

        std::vector<std::map<int, std::string>> products = this->db.GetProducts();
        std::vector<std::map<int, std::string>> materials = this->db.GetMaterials();
        std::vector<std::map<int, std::string>> suppliers = this->db.GetSuppliers();

        // products
        for (int i = 0; i < products.size(); i++)
        {
            for (int g = 0; g < 11; g++)
            {
                if (g != 1)
                {
                    if (g > 1)
                    {
                        gtk_grid_attach(GTK_GRID(this->grids[0]), gtk_label_new_with_mnemonic(products.at(i)[g].c_str()), g - 1, i, 1, 1);
                    }
                    else
                    {
                        gtk_grid_attach(GTK_GRID(this->grids[0]), gtk_label_new_with_mnemonic(products.at(i)[g].c_str()), g, i, 1, 1);
                    }
                }
            }
            //  my struct
            MyData *data = static_cast<MyData *>(g_new(MyData, 1));
            data->my_grid = this->view_panels[0];
            data->page = 0;
            data->n = i;
            //
            GtkWidget *button_red = gtk_button_new_from_icon_name("document-edit");
            g_signal_connect(button_red, "clicked", G_CALLBACK(&Window::button_clicked), data);
            gtk_grid_attach(GTK_GRID(this->grids[0]), button_red, 11, i, 1, 1);
        }
        // materials
        for (int i = 0; i < materials.size(); i++)
        {
            for (int g = 0; g < 6; g++)
            {
                if (g != 4)
                {
                    if (g > 4)
                    {
                        gtk_grid_attach(GTK_GRID(this->grids[1]), gtk_label_new_with_mnemonic(materials.at(i)[g].c_str()), g - 1, i, 1, 1);
                    }
                    else
                    {
                        gtk_grid_attach(GTK_GRID(this->grids[1]), gtk_label_new_with_mnemonic(materials.at(i)[g].c_str()), g, i, 1, 1);
                    }
                }
            }
            //  my struct
            MyData *data = static_cast<MyData *>(g_new(MyData, 1));
            data->page = 1;
            data->n = i;
            //
            GtkWidget *button_red = gtk_button_new_from_icon_name("document-edit");
            g_signal_connect(button_red, "clicked", G_CALLBACK(&Window::button_clicked), data);
            gtk_grid_attach(GTK_GRID(this->grids[1]), button_red, 6, i, 1, 1);
        }
        // suppliers
        for (int i = 0; i < suppliers.size(); i++)
        {
            for (int g = 0; g < 6; g++)
            {
                gtk_grid_attach(GTK_GRID(this->grids[2]), gtk_label_new_with_mnemonic(suppliers.at(i)[g].c_str()), g, i, 1, 1);
            }
            //  my struct
            MyData *data = static_cast<MyData *>(g_new(MyData, 1));
            data->page = 2;
            data->n = i;
            //
            GtkWidget *button_red = gtk_button_new_from_icon_name("document-edit");
            g_signal_connect(button_red, "clicked", G_CALLBACK(&Window::button_clicked), data);
            gtk_grid_attach(GTK_GRID(this->grids[2]), button_red, 6, i, 1, 1);
        }
    }
    void button_clicked(GtkButton *button, gpointer user_data)
    {
        MyData *data = static_cast<MyData *>(user_data);
        GtkWidget *my_grid = data->my_grid;
        int page = data->page;
        int n = data->n;

        // main
        //cout << n << endl;
        map<int, string> m = db.GetProduct(n);
        //map<int, string> m;
        //if (page == 0) m = this->db.GetProduct(n);
        //else if (page == 1) m = this->db.GetMaterial(n);
        //else if (page == 2) m = this->db.GetSupplier(n);
        GtkWidget *image = gtk_image_new_from_file(this->db.GetProductImg(n).c_str());
        gtk_image_set_icon_size(GTK_IMAGE(image), GTK_ICON_SIZE_LARGE);
        gtk_grid_attach(GTK_GRID(my_grid), image, 0, 0, 3, 3);
        gtk_grid_attach(GTK_GRID(my_grid), gtk_label_new_with_mnemonic("HI, dear"), 3, 3, 1, 1);
        g_free(data);
    }
};
static void activate(GtkApplication *app, gpointer user_data)
{
    Window window = Window(app, user_data);
}

int main(int argc, char **argv)
{
    GtkApplication *app;
    int status;

    app = gtk_application_new("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
    g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
    status = g_application_run(G_APPLICATION(app), argc, argv);
    g_object_unref(app);

    return status;
}

Ответы (0 шт):