I have encountered this runtime exception at the very end of the program by simply creating an instance of the specified class, so I presume the issue lies with either the constructor, copy constructor, copy assignment operator or destructor. I have read up on and followed the rule of three to the extent of my limited cpp knowledge.
Source.cpp
#include "Header.h"
#include <iostream>
using namespace std;
int main() {
string command = "CREATE TABLE table_name IF NOT EXISTS ((column_1_name,type,default_value), (column_2_name,type,default_value))";
string columns[20] = { "column_1_name,type,default_value", "column_1_name,type,default_value" };
string commandData[9] = { "table_name", "IF NOT EXISTS" };
CommCREATETABLE comm(command, columns, commandData, 2, 2);
}
Relevant code from Header.h
class CommCREATETABLE {
    string fullCommand = "";
    string* columns = nullptr;
    string* commandData = nullptr;
    string tableName = "";
    int nrOfColumns = 0;
    int nrOfElements = 0;
    bool valid = false;
Constructor:
CommCREATETABLE(string command, string* columns, string* commandData, int nrOfRows, int nrOfElements) {
        this->setNrOfColumns(nrOfRows);
        this->setNrOfElements(nrOfElements);
        this->setCommand(command);
        this->setColumns(columns);
        this->setCommandData(commandData);
        this->valid = checkInput(this->commandData, this->columns);
        this->setTableName(commandData[0]);
    }
Copy constructor, copy assignment operator, destructor:
CommCREATETABLE(const CommCREATETABLE& comm) {
        this->setNrOfColumns(comm.nrOfColumns);
        this->setNrOfElements(comm.nrOfElements);
        this->setCommand(comm.fullCommand);
        this->setColumns(comm.columns);
        this->setCommandData(comm.commandData);
        this->setTableName(comm.tableName);
        this->valid = comm.valid;
    }
    ~CommCREATETABLE() {
        if (this->columns != nullptr) {
            delete[] this->columns;
        }
        if (this->commandData != nullptr) {
            delete[] this->commandData;
        }
    }
    CommCREATETABLE& operator=(const CommCREATETABLE& comm) {
        this->setCommand(comm.fullCommand);
        this->setColumns(comm.columns);
        this->setCommandData(comm.commandData);
        this->setTableName(comm.tableName);
        this->setNrOfColumns(comm.nrOfColumns);
        this->setNrOfElements(comm.nrOfElements);
        this->valid = checkInput(this->commandData, this->columns);
        return *this;
    }
The only setters that deal with dynamic memory allocation are the following:
void setColumns(const string* columns) {
        if (this->nrOfColumns >= 0) {
            this->columns = new string[this->nrOfColumns];
            memcpy(this->columns, columns, this->nrOfColumns * sizeof(string));
        }
        else throw EmptyCommandException();
    }
    void setCommandData(const string* commandData) {
        if (this->nrOfElements >= 0) {
            this->commandData = new string[this->nrOfElements];
            memcpy(this->commandData, commandData, this->nrOfElements * sizeof(string));
        }
        else throw EmptyCommandException();
    }