So from what I understand, a SIGSEGV segmentation fault is most likely caused by either trying to access memory you aren't allowed to or dereferencing a null pointer. If I am wrong in my understanding of this, please correct me as you please. As someone who is still rather new to programming, I am having trouble finding the solution to this error in this Multiplication table problem.
main.cpp:
#include <Python.h>
#include <iostream>
//#include <Windows.h>
#include <cmath>
#include <string>
using namespace std;
/*
Description:
    To call this function, simply pass the function name in Python that you wish to call.
Example:
    callProcedure("printsomething");
Output:
    Python will print on the screen: Hello from python!
Return:
    None
*/
void CallProcedure(const string& pName)
{
    char *procname = new char[pName.length() + 1];
    std::strcpy(procname, pName.c_str());
    Py_Initialize();
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("import os");
    PyRun_SimpleString("sys.path.append(os.getcwd())");
    PyObject* my_module = PyImport_ImportModule("python_modules.my_module");
    PyErr_Print();
    PyObject* my_function = PyObject_GetAttrString(my_module, procname);
    PyObject* my_result = PyObject_CallObject(my_function, NULL);
    Py_Finalize();
    delete[] procname;
}
/*
Description:
    To call this function, pass the name of the Python functino you wish to call and the string parameter you want to send
Example:
    int x = callIntFunc("PrintMe","Test");
Output:
    Python will print on the screen:
        You sent me: Test
Return:
    100 is returned to the C++
*/
int callIntFunc(const string& proc, const string& param)
{
    char *procname = new char[proc.length() + 1];
    std::strcpy(procname, proc.c_str());
    char *paramval = new char[param.length() + 1];
    std::strcpy(paramval, param.c_str());
    PyObject *pName, *pModule, *pDict, *pFunc, *pValue = nullptr, *presult = nullptr;
    // Initialize the Python Interpreter
    Py_Initialize();
    // Build the name object
    pName = PyUnicode_FromString((char*)"python_modules.my_module");
    // Load the module object
    pModule = PyImport_Import(pName);
    // pDict is a borrowed reference
    pDict = PyModule_GetDict(pModule);
    // pFunc is also a borrowed reference
    pFunc = PyDict_GetItemString(pDict, procname);
    if (PyCallable_Check(pFunc))
    {
        pValue = Py_BuildValue("(z)", paramval);
        PyErr_Print();
        presult = PyObject_CallObject(pFunc, pValue);
        PyErr_Print();
    }
    else
    {
        PyErr_Print();
    }
    //printf("Result is %d\n", _PyLong_AsInt(presult));
    Py_DECREF(pValue);
    // Clean up
    Py_DECREF(pModule);
    Py_DECREF(pName);
    // Finish the Python Interpreter
    Py_Finalize();
    // clean
    delete[] procname;
    delete[] paramval;
    return _PyLong_AsInt(presult);
}
/*
Description:
    To call this function, pass the name of the Python functino you wish to call and the string parameter you want to send
Example:
    int x = callIntFunc("doublevalue",5);
Return:
    25 is returned to the C++
*/
int callIntFunc(const string& proc, int param)
{
    char *procname = new char[proc.length() + 1];
    std::strcpy(procname, proc.c_str());
    PyObject *pName, *pModule, *pDict, *pFunc, *pValue = nullptr, *presult = nullptr;
    // Initialize the Python Interpreter
    Py_Initialize();
    // Build the name object
    pName = PyUnicode_FromString((char*)"python_modules.my_module");
    // Load the module object
    pModule = PyImport_Import(pName);
    // pDict is a borrowed reference
    pDict = PyModule_GetDict(pModule);
    // pFunc is also a borrowed reference
    pFunc = PyDict_GetItemString(pDict, procname);
    if (PyCallable_Check(pFunc))
    {
        pValue = Py_BuildValue("(i)", param);
        PyErr_Print();
        presult = PyObject_CallObject(pFunc, pValue);
        PyErr_Print();
    }
    else
    {
        PyErr_Print();
    }
    //printf("Result is %d\n", _PyLong_AsInt(presult));
    Py_DECREF(pValue);
    // Clean up
    Py_DECREF(pModule);
    Py_DECREF(pName);
    // Finish the Python Interpreter
    Py_Finalize();
    // clean
    delete[] procname;
    return _PyLong_AsInt(presult);
}
void DisplayMenuItems(bool* close) {
    int choice;
    int number;
    int x;
    cout << "1: Display a Multiplication Table" << endl;
    cout << "2: Double a value" << endl;
    cout << "3. Exit program" << endl;
    cout << "Enter your selection as a number 1, 2, or 3." << endl;
    cin >> choice;
    if (choice == 1) {
        cout << "Enter a number: " << endl;
        cin >> number;
        callIntFunc("MultiplicationTable", number);
    }
    else if (choice == 2) {
        cout << "Enter a number: " << endl;
        cin >> x;
        callIntFunc("DoubleValue", x);
    }
    else if (choice == 3) {
        cout << "Exiting program" << endl;
        *close = true;
        return;
    }
    else {
        cout << "You have entered an invalid choice, please try again" << endl;
    }
}
int main()
{
    bool close = false;
    while (!close) {
        DisplayMenuItems(&close);
    }
    return 0;
}
The output is failing to complete the program by displaying the multiplication table and instead displays an interrupted signal as shown below:

