Ошибка Thread 1: EXC_BAD_ACCESS (code=1, address=0x0) при компиляции

279
07 февраля 2020, 14:40

Необходимо написать класс для работы с целыми знаковыми числами с использованием stl и виртуальных функций.(С++03). Ошибка в строке 235 ''CIntN tmp = -((dynamic_cast(arr[0])))''

#include <algorithm>
#include <iostream>
#include <iterator>
#include <fstream>
#include <sstream>
#include <vector>
class CIntN {
protected:
    std::string filename;
    std::vector<int> nums;
    class Adder {
        int carry;
    public:
        Adder(): carry(0) {}
        int operator()(int x, int y) {
            int oldcarry = carry;
            carry = (x + y + oldcarry) / 10;
            return (x + y + oldcarry) % 10;
        }
    };
    class Invertor {
    public:
        int operator()(int x) {
            return 9 - x;
        }
    };
public:
    virtual int output(const char* FileName = NULL) = 0;
    virtual CIntN& with(const char* str = NULL);
    virtual CIntN& operator=(const CIntN&);
    virtual CIntN* operator-() const = 0;
    virtual CIntN& operator+=(const CIntN&);
    virtual CIntN& operator-=(const CIntN&);
    virtual CIntN& negate();
    virtual ~CIntN() {
    };
};
CIntN& CIntN::with(const char *str) {
    std::stringstream ss((std::string(str)));
    int num;
    ss >> num;
    ss >> filename;
    int n;
    ss >> n;
    nums = std::vector<int>(n + 1, 0);
    std::string number;
    ss >> number;
    std::string::reverse_iterator end = number.rend();
    std::vector<int>::reverse_iterator vit = nums.rbegin();
    if (number[0] == '-' || number[0] == '+') --end;
    for (std::string::reverse_iterator it = number.rbegin(); it != end
         && vit != nums.rend(); ++it, ++vit) {
        *vit = *it - '0';
    }
    if (number[0] == '-') {
        negate();
    }
    return *this;
}
CIntN& CIntN::negate() {
    std::transform(nums.begin(), nums.end(), nums.begin(), Invertor());
    int carry = (*(nums.rbegin()) + 1) / 10;
    *(nums.rbegin()) = (*(nums.rbegin()) + 1) % 10;
    std::vector<int>::reverse_iterator it = nums.rbegin() + 1;
    for (; it < nums.rend(); ++it) {
        int oldcarry = carry;
        carry = (*it + oldcarry) / 10;
        *it = (*it + oldcarry) % 10;
    }
    return *this;
}
CIntN& CIntN::operator=(const CIntN& other) {
    nums.clear();
    std::copy(other.nums.begin(), other.nums.end(), std::back_inserter(nums));
    return *this;
}
CIntN& CIntN::operator+=(const CIntN& other) {
    if (nums.size() != other.nums.size()) {
        std::cerr << "Attempt to add CIntN's with different sizes!" << std::endl;
    }
    std::transform(nums.rbegin(), nums.rend(), other.nums.rbegin(), nums.rbegin(), Adder());
    return *this;
}
CIntN& CIntN::operator-=(const CIntN& other) {
    CIntN *tmp = -other;
    *this += *tmp;
    delete tmp;
    return *this;
}
class CIntN0: public CIntN {
public:
    CIntN0() {
        nums = std::vector<int>();
    }
    CIntN0(const CIntN0& n0) {
        nums = std::vector<int>(n0.nums);
    }
    int output(const char* FileName = NULL) {
        std::ofstream of;
        if (FileName) {
            of.open(FileName);
        } else {
            of.open(filename.c_str());
        }
        of << nums.size() - 1 << " ";
        std::vector<int>::iterator it = nums.begin();
        if (nums[0] >= 5) {
            of << '-';
            negate();
        }
        while (*it == 0 && it != nums.end()) ++it;
        if (it == nums.end()) {
            of << 0;
        } else {
            std::copy(it, nums.end(), std::ostream_iterator<int>(of, ""));
        }
        of << std::endl;
        of.close();
        return 0;
    }
    CIntN* operator-() const {
        CIntN0 *ci = new CIntN0(*this);
        ci->negate();
        return ci;
    }
    ~CIntN0() {
    }
};
CIntN0 operator+(const CIntN0 &first, const CIntN0 &second) {
    CIntN0 res(first);
    res += second;
    return res;
}
CIntN0 operator-(const CIntN0 &first, const CIntN0 &second) {
    CIntN0 res(first);
    res -= second;
    return res;
}
class CIntN1: public CIntN {
public:
    CIntN1() {
        nums = std::vector<int>();
    }
    CIntN1(const CIntN1& n1) {
        nums = std::vector<int>(n1.nums);
    }
    int output(const char* FileName = NULL) {
        std::ofstream of;
        if (FileName) {
            of.open(FileName);
        } else {
            of.open(filename.c_str());
        }
        of << nums.size() - 1 << std::endl;
        std::vector<int>::iterator it = nums.begin();
        if (nums[0] >= 5) {
            of << '-';
            negate();
        }
        while (*it == 0 && it != nums.end()) ++it;
        if (it == nums.end()) {
            of << 0;
        } else {
            std::copy(it, nums.end(), std::ostream_iterator<int>(of, ""));
        }
        of << std::endl;
        of.close();
        return 0;
    }
    CIntN* operator-() const {
        CIntN1 *ci = new CIntN1(*this);
        ci->negate();
        return ci;
    }
    ~CIntN1() {
    }
};
CIntN1 operator+(const CIntN1 &first, const CIntN1 &second) {
    CIntN1 res(first);
    res += second;
    return res;
}
CIntN1 operator-(const CIntN1 &first, const CIntN1 &second) {
    CIntN1 res(first);
    res -= second;
    return res;
}
class CIntNFactory {
    int i;
public:
    CIntNFactory(int i): i(i) {};
    CIntN *createCIntN(const char* str);
    ~CIntNFactory() {
    }
};
CIntN *CIntNFactory::createCIntN(const char *str) {
    CIntN *ci;
    if (i == 0) {
        ci = new CIntN0();
    } else if (i == 1) {
        ci = new CIntN1();
    } else return NULL;
    ci->with(str);
    return ci;
}
CIntN *CreateCIntN(const char *str, CIntNFactory** factories) {
    return factories[str[0] - '0']->createCIntN(str);
}
int main() {
    std::string str;
    CIntNFactory **factories = new CIntNFactory*[2];
    factories[0] = new CIntNFactory(0);
    factories[1] = new CIntNFactory(1);
    std::ifstream in("input.txt");
    std::vector<CIntN*> arr;
    while (std::getline(in, str)) {
        arr.push_back(CreateCIntN(str.c_str(), factories));
    }
    CIntN *tmp = -(*(dynamic_cast<CIntN0*>(arr[0])));
    tmp->output("output6.txt");
    delete tmp;
    (*(dynamic_cast<CIntN1*>(arr[1])) + *(dynamic_cast<CIntN1*>(arr[3]))).output("output5.txt");
    for (std::vector<CIntN*>::iterator it = arr.begin(); it != arr.end(); ++it) {
        (*it)->output();
        delete *it;
    }
    delete factories[0];
    delete factories[1];
    delete[] factories;
    return 0;
}
READ ALSO
Аппаратный генератор случайных чисел

Аппаратный генератор случайных чисел

Нашел в интернете код, где используется аппаратный генератор случайных чиселХабр

254
как разделить очень очень длинное число, такое как Фибоначчи на очень мелкие части

как разделить очень очень длинное число, такое как Фибоначчи на очень мелкие части

Дело в том что мой код не может отобразить все число даже unsigned long long кажется очень мелким, я думаю использовать int и разделения между длиной...

229
Как &ldquo;обновить&rdquo; openGL в SFML?

Как “обновить” openGL в SFML?

В SFML есть возможность использование openGL (логично), однако его версия 11 - слишком старая

237
Числа Фибоначчи. Объяснить код

Числа Фибоначчи. Объяснить код

Дано: Для решения задачи считываем два целых числа i и j такие, что 1 ≤ i, j ≤ 10^6

275