Задать вопрос
Ответы пользователя по тегу C++
  • Почему код выкидывает исключение переполнение стека?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    У вас массив внутри класса, класс - локальная переменная. Получается массив на стеке. На 4 миллиона ячеек. Но стек ограничен и вот он переполняется. Стандартного размера не хватает. Надо поднять размер стека опциями линкера.

    Или экземпляр класса создавайте в куче, через new, и храните в unique_ptr.

    А по коду: не используйте эту сишную арифметику указателей. У вас двумерный массив, вы и обращайтесь везде через 2 индекса в квадратных скобках. Так понятнее код будет.
    Ответ написан
    Комментировать
  • Почему не удаётся освободить память в деструкторе?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Проблема вот в этой строчке:
    int get_num_from_BigInteger(BigInteger big_int){

    Тут у вас идет передача по значению. У вас создается новая BigInteger переменная, со значением переданной. Поскольку вы конструктор копирования нигде не определили, компилятор сделал его вам сам, и там он тупо копирует все данные класса, включая указатель arr.
    В итоге у вас получается два экземпляра класса, в каждом из которых указатель на один и тот же массив. Потом каждый из двух экземпляров в деструкторе вызовет free для одного и того же указатенля, вот и получается двойной free и креш.

    Вам надо руководствоватся правилом трех(пяти). Доопределите конструктор копирования. Вообще, вам бы стоило его запретить (= delete;), ибо копировать такие большие числа - это плохо. А в функции ваши передавайте BigInteger по константной ссылке.

    Ну и в других функциях та же самая поблема.

    И еще, в C++ не стоит использовать malloc/free, используйте new/delete. А еще лучше, используйте std::vector.
    Ответ написан
    Комментировать
  • Почему выдается неправильный результат при операциях c long int в Си?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Проблема в выводе. Вы пытаетесь вывести переменную unsigned long long через спецификатор "%d". Надо использовать "%llu" какой-нибудь.
    Ответ написан
    Комментировать
  • Почему программа не работает?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Проблема в том, что сначала пытаетесь вычислить a^(p-2), а потом взять его по модулю. В задаче числа до 10^9 и если вы попытаетесь вычислить что-то вроде 99999^1000005, то у вас int переменная переполнится, потому что там должны быть миллионы знаков в числе, а в int едва 10 влезает.

    Надо брать по модулю при каждом умножении в возведении в степень.

    Потому что (a*b)%p = (a%p)*(b%p) % p.

    Edit:

    Еще две ошибки: считать произведение надо в long long, потму что 10^9*10^9 в int не влезает.
    И fast_deg(a, deg/2) надо вызывать только один раз, а то у вас функция работает за O(n) вместо O(log n).
    Ответ написан
    2 комментария
  • Как считать числа из текстового файла в массив на с++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вы правильно начали, заведите vector и делайте туда push_back.

    Читайте циклом while, пока чтение не вернет ошибку:
    int x;
    ifstream f("file.txt");
    while (f >> x) {
      v.push_back(x);
    }
    Ответ написан
    5 комментариев
  • Почему не получается записать данные в память?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    У вас rBuffer зануляется перед выделением памяти?

    Еще стоит проверять размер выделенной памяти. shellSize может вернуться больше исходного размера и вы потом в Write будете записывать больше данных, чем у вас в shellCode есть.
    Ответ написан
    Комментировать
  • Почему не работает программа на C++ с решением задачи об "Игре в жизнь"?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    У вас ошибка в логике: вы меняете поле отдельно в каждой клетке. И потом используете уже поменянные клетки для подсчета количества соседей в следующей клетке. Но в игре жизнь все клетки считаются параллельно.

    Для этого вам понадобится 2 массива map. Один для текущей итерации, и другой для следующей. Или массив должен быть не bool, а int, и там вы должны разными числами помечать живые клетки, которые умрут, живые клетки, пустые клетки и пустые клетки, которые родятся. В первый проход вы считаете соседей и помечаете клетки, а вторым проходом все изменения применяете.

    Кажется, из-за этого у вас там поле никогда не вымирает и программа не останавливается.
    Ответ написан
    1 комментарий
  • Почему объект не передается по ссылке?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Код конструктора-то дайте. И заодно отметьте, на какую конкретно строчку компилятор ругается.

    Скорее всего у вас внутри конструктора BoxContainer идет присвоение в член nbox. Но у вас не определен оператор присвоения (или конструктор копирования) для NumberBox. Определите его (можно default). Так что с передачей по ссылке все хорошо, но вот то, что вы дальше с этой ссылкой пытаетесь сделать у вас не работает.

    Руководствуйтесь правилом трех-пяти.
    Ответ написан
    2 комментария
  • Почему не работает выражение в интерпретаторе?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Отладчик есть? Или хотя бы отладочный вывод добавьте. Выводите все переменные там, где они меняются. Мне кажется, что вы из строк все пробелы удаляете и у вас segment получается "sqrt(x);". Ведь stringstream будет читать одно слово целиком до пробельного символа, а их там тупо нет. И потом проверка segment == "sqrt" не срабатывает. Но мне лень ваш код запускать, перепроверьте эту гипотезу сами.

    Вообще у вас тут этап токенизации пропущен. Надо сначала разбить входную строку на токены - имена переменных, числа, функции, операторы, скобки, точки с запятой - вот все сущности, что у вас есть в программе. Уже по этому потом разбирать. Вы же пытаетесь и разбор выражения и токенизацию вперемешку сделать и у вас то тут то там что-то ломается.
    Ответ написан
    Комментировать
  • Как получить нужное значение на разных версиях виндовс?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Заведите, например enum со всеми версиями виндоуз и занумеруйте их. Смещения ваши раскладывайте не по неймспейсам, а массиве. Во время исполнения через winapi получайте версию винды и приводите ее к значению в вашем энуме. Его используйте как индекс в массиве.
    Ответ написан
    2 комментария
  • Не могу найти ошибку в коде?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Одна из ошибок - имена переменных не отчищаются от пробелов до и после при присваивании. Поэтому вы присваиваете значение в " x ", а читаете из "x" и это не работает.
    Ответ написан
  • Как нагрузить расчёт в однопоточной программе C++ до 90-100% на используемом ядре?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Во-первых, вы уверены, что у вас эти 10-15% - это загрузка ядра, а не вcего процессора? Диспетчер задач обычно показывает как 100% полную загрузку всех ядер.
    Во-вторых, что у вас там за вычесления? Работа с целыми числами? Float? Всякие векторные инструкции? Точно нет никаких пауз вроде sleep()?

    Выделение памяти медленное, да, но это потому что надо много вычислений сделать, чтобы найти какой-же кусок памяти выдать программе.

    Самое вероятное место для тормозов - это вывод на экран/в файл. Если вы много отладочной информации выводите, это будет бутылочным горлышком.

    Теоретически очень активное обращение к памяти тоже будет тормозить, особенно, если памяти не хватает и идет работа с файлом подкачки.
    Ответ написан
  • Почему эта программа вычисляет факториал больших чисел неправильно?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Полная фигня с распараллеливанием. Ну нельзя длинное число параллельно умножать сразу на много чисел. Во-первых, там гонка данных. Один поток может прочитать цифру, домножить ее на текущее число, в это время другой поток запишет свой результат, и тут первый поток этот результат перезапишет. Результат работы одного из потоков просто потерян. Но даже без этого - каждый поток должен видеть все цифры числа как они были, когда он начал умножать. Если какой-то другой поток там хоть что-то запишет - у вас бред будет.

    Правильное распараллеливание будет в умножении на одно число. Каждый поток домножает на число свой промежуток цифр и делает перносы только внутри своего отрезка цифр. Потом все потоки спят, а один делает переносы между границами отрезков и расширяет вектор, делая переносы в конце. При этом у вас в числе какие-то разряды будут больше базы. Потом потоки продолжают умножать уже на следующее число. Надо их синхронизировать какими-то заборами/событиями между каждым новым числом. В конце придется нормализовать число в один поток. Возможно это можно тоже распараллелить, но это сложно будет совсем.
    Ответ написан
    Комментировать
  • Данные в таком случае будут хранится в стеке?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    В наше время можно просто проверить: godbolt.org

    И clang и g++ и при локальном и при глобальном объявлении кладут 1 на стек.
    Правда, clang чуть поумнее и выдает warning:
    warning: temporary whose address is used as value of local variable 'Number' will be destroyed at the end of the full-expression [-Wdangling]


    Нельзя надеяться, что по этому адресу останется лежать 1. В более сложных случаях этот адрес может быть переиспользован под что-то еще. Обращение по такому указателю - UB.
    Ответ написан
    Комментировать
  • Рандом маленькой разброс, как увеличить в рамках диапазона?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Можно, например, не вызывать srand, если у вас эта программа запускается несколько раз в секунду. Если реже, то все с программой хорошо, просто ваше представление о случайности не правильное.
    Ответ написан
    Комментировать
  • Undefined behavior в C++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Скомпилирует любой компилятор с++. Может выдать ворнинги, если включена опция реагировать на предупреждения, как на ошибки, то тогда не скомпилирует, но только потому что его конкретно об этом попросили. Это не ошибка компиляции.

    В этом главная проблема Undefined Behavior: компилятор его почти всегда не видит, и программа с ним может даже работать в каких-то случаях так, как программист задумывал. А в других совершенно необъяснимо падает или выдает бред.

    У ОС защита от такой наглости с памятью, конечно, есть. Такая программа рано или поздно упадет с access violation, segmentation fault или еще чем-то подобным, когда цикл дойдет до не вашей памяти.
    Ответ написан
    Комментировать
  • С++ автоматически вставляет в функцию ссылку на вектор?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Это называется "передача по ссылке". Гуглите.
    Ответ написан
    Комментировать
  • C++ std::cout не выводит ничего?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Разность в поведении между сборками может быть обусловлена двумя причинами:
    1) в коде есть ifdef и часть функциональности просто отключена в релизной сборке. Довольно часто так намеренно отключают отладочный вывод.
    2) В коде есть ошибка, какое-то undefined behavior и при оптимизации в релизной сборке часть кода вырезается компилятором.

    Какой-то другой причины чтобы cout не работал в релизной сборке я не вижу.

    printf вы наверное сами куда-то добавили. Если заменить в коде библиотеки отсутствующий cout на printf оно так же работает? Или у вас нет доступа к коду?
    Ответ написан
    5 комментариев
  • Откуда появляется это странное число?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Читайте код внимательно:
    Ввод:
    for (int i=0; i<x; i++){

    Вывод:
    for (int i = 0; i <= x; i++){

    У вас там <= в конце. Из-за этого идет обращение к элементу по индексу x, за границей массива. И оттуда выводится какой-то мусор - это и есть ваше странное число.
    Ответ написан
    Комментировать
  • Насколько больше будет занимать памяти Свойство (get + set)?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Ну так тут у вас функции тоже есть. Эти две ваших лябды окажутся какими-то фнукциями, которые компилятор куда-то засунет, и в классе к вас будут 2 переменные, хранящие адресс этих функций.

    Если вы сделаете просто методы Get и Set, то будут точно такие же 2 функции в памяти. Важно, что в вашем текущем и в предолженном решении функции не храянятся в эксземплярах объекта. Обычно они в коде программы встречаются ровно по одному разу*.

    *Если не учитывать инлайнинг функций. Иногда компилятор вместо вызова тупо вставлят тело функции в код. Но это не сильно увеличивает размер кода обычно. И никак не зависит от количества и размера объектов в памяти.
    Ответ написан
    Комментировать