Выход из рекурсивного кода с кодом выхода 3221225477 - PullRequest
0 голосов
/ 19 ноября 2018

Я новичок в программировании на С ++ и StackOverflow, но у меня есть некоторый опыт работы с ядром Java. Я хотел участвовать в олимпиадах по программированию, и я выбрал c ++, потому что коды c ++, как правило, быстрее, чем у эквивалентного кода Java.

Я решал некоторые проблемы, связанные с рекурсией и DP на зональном уровне, и я столкнулся с вопросом, называемым Sequence game

Но, к сожалению, мой код не работает. Он выходит с кодом выхода 3221225477, но я ничего не могу сделать из этого. Я помню, что Java гораздо лучше показывал мои ошибки, но здесь, в c ++, я не имею понятия, что происходит. Вот код между прочим,

#include <iostream>
#include <fstream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
int N, minimum, maximum;
set <unsigned int> result;
vector <unsigned int> integers;
bool status = true;

void score(unsigned int b, unsigned int step)
{
    if(step < N)
    {
        unsigned int subtracted;
        unsigned int added = b + integers[step];
        bool add_gate = (added <= maximum);
        bool subtract_gate = (b <= integers[step]);
        if (subtract_gate) 
            subtracted = b - integers[step];
        subtract_gate = subtract_gate && (subtracted >= minimum);
        if(add_gate && subtract_gate)
        {
            result.insert(added);
            result.insert(subtracted);
            score(added, step++);
            score(subtracted, step++);
        }
        else if(!(add_gate) && !(subtract_gate))
        {
            status = false;
            return;
        }
        else if(add_gate)
        {
            result.insert(added);
            score(added, step++);
        }
        else if(subtract_gate)
        {
            result.insert(subtracted);
            score(subtracted, step++);
        }
    }
    else return;
}
int main()
{
    ios_base::sync_with_stdio(false);

    ifstream input("input.txt"); // attach to input file
    streambuf *cinbuf = cin.rdbuf(); // save old cin buffer
    cin.rdbuf(input.rdbuf()); // redirect cin to input.txt

    ofstream output("output.txt"); // attach to output file
    streambuf *coutbuf = cout.rdbuf(); // save old cout buffer
    cout.rdbuf(output.rdbuf()); // redirect cout to output.txt

    unsigned int b;
    cin>>N>>b>>minimum>>maximum;

    for(unsigned int i = 0; i < N; ++i)
        cin>>integers[i];
    score(b, 0);
    set<unsigned int>::iterator iter = result.begin();
    if(status)
        cout<<*iter<<endl;
    else 
        cout<<-1<<endl;

    cin.rdbuf(cinbuf);
    cout.rdbuf(coutbuf);

    return 0;
}

(Примечание: я специально не использовал typedef).

Я скомпилировал этот код с помощью mingw-w64 на машине с Windows, и вот вывод:

[Закончено в 19.8 с кодом выхода 3221225477] ...

Несмотря на то, что у меня есть intel i5-8600, компиляция заняла так много времени, антивирус отнимал много времени для сканирования моего exe-файла, и даже иногда он долго компилируется без какого-либо вмешательства со стороны антивирусной программы. -virus.

(Примечание: я не использовал командную строку, вместо этого я использовал возвышенный текст для его компиляции). Я даже попробовал tdm-gcc, и снова появился какой-то другой специфический код выхода. Я даже пытался запустить его на компьютере с Ubuntu, но, к сожалению, он не смог найти выходной файл. Когда я запустил его на Codechef Online IDE , хотя он не работал должным образом, но сообщение об ошибке было менее страшным, чем у mingw. Он сказал, что произошла ошибка во время выполнения, и «SIGSEGV» было отображено в виде кода ошибки. Codechef утверждает, что

SIGSEGV - это ошибка (сигнал), вызванная неверной ссылкой на память или ошибка сегментации. Вы, вероятно, пытаетесь получить доступ к массиву элемент за пределами или пытается использовать слишком много памяти. Некоторые из Другие причины ошибки сегментации: Использование неинициализированного указатели, разыменование пустых указателей, доступ к памяти, Программа не принадлежит.

Уже несколько дней я пытаюсь решить эту проблему, и сейчас я действительно расстроен. Сначала, когда я начал решать эту проблему, я использовал массивы c, затем переключился на векторы, и, наконец, теперь на std :: set, но решил, что это решит проблему, но ничего не помогло. Я пробовал другую проблему с дп, и снова это имело место.

Было бы здорово, если бы кто-нибудь помог мне выяснить, что не так в моем коде. Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 19 ноября 2018

integers - это vector, который является динамическим непрерывным массивом, размер которого здесь не известен во время компиляции.Поэтому, когда он определен изначально, он пуст.Вам нужно вставить в vector.Измените следующее:

for(unsigned int i = 0; i < N; ++i)
    cin>>integers[i];

на следующее:

int j;
for(unsigned int i = 0; i < N; ++i) {
    cin>> j;
    integers.push_back(j);
}
0 голосов
/ 19 ноября 2018

PW ответ правильный, но альтернативой использованию push_back является предварительное выделение вектора после того, как N станет известным.Затем вы можете читать из cin прямо в векторные элементы, как и раньше.

integers = vector<unsigned int>(N);
for (unsigned int i = 0; i < N; i++)
    cin >> integers[i];

Этот метод имеет дополнительное преимущество, заключающееся в том, что выделяется память для вектора только один раз.Метод push_back будет перераспределен, если основной буфер заполнится.

0 голосов
/ 19 ноября 2018

3221225477, преобразованный в шестнадцатеричный код, равен 0xC0000005, что означает STATUS_ACCESS_VIOLATION , что означает, что вы пытались получить доступ (чтение, запись или выполнение) к недействительной памяти.

Я помню, что Java гораздо лучше показывал мои ошибки, но здесь, в c ++, я понятия не имею, что происходит.

Когда вы запускаетев вашей программе сбой, вы должны запустить его под отладчиком.Поскольку вы запускаете свой код в Windows, я настоятельно рекомендую Visual Studio 2017 Community Edition.Если вы запускаете свой код под ним, он будет указывать точную строку, где происходит сбой.

Что касается самого вашего сбоя, как указывает PaulMcKenzie в комментарии, вы индексируете пустой вектор, что составляет std::cin записать в запредельную память.

...