Задать вопрос
  • Как "забыть" переменную на c/c++?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега C
    Седой и строгий
    Переменные прекращают существование после завершения блока, в котором объявлены. Соответственно, используйте маленькие функции, объявляйте переменные как можно ближе к месту их использования и компилятор обо всём позаботится сам.
    Ответ написан
    Комментировать
  • Почему можно обратиться к объекту через указатель со значением nullptr?

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

    P.s. сказанное выше не относится к виртуальным функциям. Там указатель на функцию храниться в vtable в экземпляре класса и вызов через nullptr скорее всего упадет.
    Ответ написан
    Комментировать
  • Как реализовать copy on write class?

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

    Нужен счетчик ссылок на буфер. Перед записью проверяйте, что счетчик равен 1. Иначе копируете данные и в текущем объекте заменяете указатель на новый буфер.

    Счетчик должен храниться где-то вместе с буфером и является частью умного указателя.

    Можно использовать std::shared_ptr - там уже этот счетчик реализован (use_count).
    Ответ написан
    Комментировать
  • Что нужно знать, чтобы написать web server на C++?

    @res2001
    Developer, ex-admin
    Полноценный веб сервер - это очень сложное ПО. Сам по себе протокол HTTP оброс кучей дополнений и улучшений, только посмотрите список RFC, его описывающих. В одиночку написать с нуля что-то подобное, например, apache - практически не посильное дело.
    Кроме HTTP, конечно, нужно хорошо знать и понимать сетевое программирование, параллельное программирование, английский язык, что-то еще.

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    А зачем это делать? Чем вас 8 хедеров не устраивают? Если уж так хочется сэкономить строчки в коде пользователей библиотеки, то можно воспользоваться рекурсивностью препроцессора и сделать хедер с 8 инклудами. Копипастить код точно не надо.
    Ответ написан
    1 комментарий
  • Как исправить ошибку "Нарушение прав доступа при записи по адресу"?

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

    Или у вас там неинициализированный указатель, или выход за границы массива, или что-то подобное. Надо присмотреться ко всем указателям в программе.

    Можно во время отладки нажать на "продолжить" и тогда дебаггер остановится именно на той инструкции, которая вызвала ошибку. Дальше уже можно смотреть, в какую переменную вы там пишите и откуда она взялась.

    Падает оно потому, что нельзя string читать и писать в файл вот так, просто интенрпретируя память объекта как char*. Потому что string содержит в себе указатели на динамически выделенную память.

    Поэтому, когда вы его (в составе AutoBase) пишите в файл а потом читаете, вы получаете указатель на адрес, который был жив вместе со старым экземпляром класса. Однако, после удаления этого старого экземпляра, этот адрес уже вам не принадлежит.

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    analiz(func(n));

    Вот тут вы вызываете функцию func и передаете результат ее работы в analiz. Хотя analiz хочет получать функцию. Надо делать так: analiz(&func);
    Ответ написан
    4 комментария
  • Почему транслятор ожидает указатель в моем коде?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Параметр функции int arr[],

    Но далее у вас arr[i][j]. Компилятор пытается взять индекс j, но перед ним же уже число. Вот он вам и говорит "начальника, индекс я у массива (указателя) взять могу, а тут число, непонятно".

    Вы обращаетесь с одномерным массивом, как будто бы он двумерный.
    Ответ написан
    Комментировать
  • Ошибка при создании статической сборки Qt 5.14.2. Что делать?

    Adamos
    @Adamos
    Много видеороликов посмотрел

    Нужно больше роликов!
    Пока даже задать вопрос так, чтобы на него можно было дать ответ, не получилось.
    Ответ написан
    7 комментариев
  • Можно ли использовать TCP протокол для игрового сервера?

    @rPman
    Во первых, собирай статистику по фреймам, смотри на графиках, почти наверняка это будут периодические пики с превышением времени на доставку данных

    Между фреймами не должна стоять фиксированная пауза, правильный подход - засекаешь время, отправляешь запрос по сети, обрабатываешь его и затем вычисляешь, сколько времени осталось ждать

    Твой подход - это как игра на сервере с помощью удаленного управления, сервер просчитывает все состояние мира а на клиенты приходит полное состояние мира на момент времени (а для оптимизации только та часть что нужна для отображения). Лаги в этом случае наиболее заметные и сложны к исключениями

    Необходимо в логику обработки игры добавить поведение в случае если время на доставку пакета превысило допустимый лимит (твои 200мс) и вот тут окажется что правильная реализация когда клиент додумывает поведение (например персонаж продолжает движение с предыдущего кадра) а когда реальная информация все же доходит, состояние мира (точнее его части - залагавшего объекта и остальных связанных с ним) откатывается назад до верного состояния. Для игрока это выглядит как расколбас, персонажа откидывает назад.

    Просто логически подумав ты поймешь что синхронизировать весь мир оказывается порочная и неудобная практика, высокий сетевой трафик (особенно на сервере как квадрат от количества игроков) уже сам по себе становится причиной лагов и можешь прийти к следующей логике:
    * все клиенты дублируют функционал сервера в расчете и валидации поведения объектов (исключение, критичные для геймплея результаты, основанные на 'рандоме', это оставить придется за сервером)
    * сервер должен выполнять роль валидатора, арбитра, у которого клиенты спрашивают - все ли участники правильно себя ведут, а по факту и логике - сервер будет еще один клиент, с функцией наведения связей (коннекта) между клиентами
    * клиентам и серверу достаточно рассылать информацию о действиях, ведущих к изменениям в мире, нет нужды рассылать координаты на каждый фрейм, если достаточно слать нажатые кнопки (точнее команды к действия - начало движения, остановка, начало поворота, конец поворота, выстрел и т.п.)
    Есть действия - критичные к оперативности, от которых зависит корректность расчета состояния мира, а есть те что отвечают только за визуальную составляющую, например поворот головы персонажа, которую например он делает при движении мыши, - визуализация, она может опоздать и быть не точной, а вот в момент выстрела необходимо отправить точную и оперативную информацию об угле поворота
    * клиенты должны додумывать действия друг друга, какой-никакой алгоритм должен быть, в простом виде - продолжить предыдущее движение, а лучше определить вручную или собирать статистику по каждому типу событий и задать свою логику (например поворот - продолажется, а вот выстрел повторным не производится)
    * само собой функционал синхронизации состояния мира никуда не девается, как минимум для первоначального наполнения клиентов, для валидации и периодического восстановления состояния из-а ошибок в сетевом протоколе

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

    При указанной реализации становится уже не так важно, используется ли tcp или udp, точнее алгоритм должен допускать что данные могут запаздывать, приходить не вовремя или вообще не приходить, а это значит udp - становится идеальным вариантом.

    Но главное, сетевой трафик в такой схеме значительно снижается, ведь рассылаются буквально только нажимаемые клавиши и изредка хеш-суммы состояния мира для валидации их корректности (все клиенты и сервер по завершению каждого фрейма должны сравнить состояния друг друга например путем вычисления хеш суммы по отсортированным объектам, всем или по какому то критерию, например попадающим в ячейку матрицы по координатам, если там происходили изменения)
    Ответ написан
    Комментировать
  • Какая книга по С++ мне лучше подойдёт?

    @res2001
    Developer, ex-admin
    Вам нужна книга, которую прочитаешь и сразу в "сеньоры" можно идти?
    Боюсь такой нет. Только практика и еще раз практика.

    Из продвинутых книг могу посоветовать:
    1. Эффективный и современный С++. 42 рекомендации по использованию C11 и C14
    в ней очень толково описаны нововведения в стандартах уже не совсем свежих, но эти нововведения чуть ли не самое главное изменение в языке до сих пор.
    2. Параллельное программирование на С++ в действии. Практика разработки многопоточных программ
    3. Оптимизация программ на C++. Проверенные методы повышения производительности.
    Ответ написан
    2 комментария
  • Существует ли тенденция избегать size_t, если это возможно?

    gbg
    @gbg Куратор тега C++
    Любые ответы на любые вопросы
    Если есть риск присванивания знакового значения в беззнаковое, компилятор выдаст WARNING

    Гораздо опаснее пихать всюду int, особенно в качестве индексов массивов и размеров. Потому что в какой-то момент кто-то захочет посчитать больше 2^31 штук объектов.

    Выдержка из материала по ссылке:
    большое количество диагностических сообщений, выдаваемых анализатором Viva64, связанны именно с рекомендацией использования memsize-типов. Использование memsize типов (таких как size_t, ptrdiff_t, INT_PTR) в 64-битных программах, вместо 32-битных типов (int, unsigned) позволяет:

    Построить компилятору более простой и, следовательно, более быстрый код, в котором будут отсутствовать лишние преобразования 32-битных и 64-битных данных. Особенно это полезно при работе с адресной арифметикой и индексации массивов.
    Избежать ряда ошибок при обработке большого объема входных данных, когда количество обрабатываемых элементов превышает количество UINT_MAX.
    Избежать ряда других, более специфичных ошибок.
    Сделать код более переносимым между 64-битными Windows и Linux системами, в которых используются различные модели данных. Так, например, в Linux системах для индексации больших массивов можно использовать тип unsigned long, а в Windows нет.
    Ответ написан
    7 комментариев
  • Не компилируется код. Как исправить ошибку?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Во-первых, вы что-то путаете. Это не при компиляции происходит, а при запуске программы. Во-вторых, вы можете открыть окно "стек вызова" справа внизу, и посмотреть, какой код в вашей программе вызвал это исключение. Вы окажетесь на конкретной строчке, где вы обращаетесь к несуществующей памяти. Это скорее всего будет обращение к массиву у вас. После этого вам остается лишь немного подумать - а почему же идет обращение к не существуюущей памяти в этой строчке? Проверьте размер массива, чему равен индекс.
    Ответ написан
    Комментировать
  • Почему возникает ошибка c std::mutex при makefile gtest?

    gbg
    @gbg Куратор тега C++
    Любые ответы на любые вопросы
    Компилятор С++ пенсионного возраста, или не настроен C++ >= С++11

    -проверить, что компилятор новый (GCC 11й версии или Clang 12й)
    -добавить флаг -std=c++17
    Ответ написан
    Комментировать
  • Как правильно называть пространства имён в проекте?

    GavriKos
    @GavriKos
    Стив Макконнелл - Совершенный код. Вот вам гайд
    Ответ написан
    3 комментария
  • Почему lambda не захватывает this?

    gbg
    @gbg Куратор тега C++
    Любые ответы на любые вопросы
    Банальная порча всех итераторов, ссылок и указателей в тот момент, когда вы вызываете emplace у вашей свалки потоков второй раз. Лечение - избавиться от переаллокации при вызове emplace, путем вызова reserve(), или использовать контейнер, который не передвигает свое содержимое туда-сюда, например, std::list
    Ответ написан
    Комментировать
  • Почему конструктор по умолчанию считается удаленным для моего класса?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    PurifiedElement_Constants не имеет конструктора по умолчанию (очень неудобные названия у вас ElementPurified_Constant vs PurifiedElement_Constants - обратите внимание, ошибка не про ваш класс, а про тип _properties).

    Т.е. член _properties в вашем классе нельзя сконструировать без каких-то параметров.

    Вам надо в вашем конструктрое класса явно вызывать конструктор _properties с какими-то параметрами:
    Machinarium::Materials::ElementPurified_Constant::ElementPurified_Constant()
        : _properties(some, valid, parameters)
    {
    }
    Ответ написан
    4 комментария
  • Как называть указатели?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    В данном примере - никак. Эта переменная тут не нужна, вместо нее можно везде, где нужен адрес, писать &conteiner1. Ради экономии одного символа заводить еще одну переменную - плохая идея.

    Если же у вас будет какая-то функция, которой нужен указатель, то ей можно аргуаментом указать Conteiner* conteiner или еще что там больше по смыслу подходит.
    Ответ написан
    Комментировать
  • Почему бекенд не пишут на С++?

    Adamos
    @Adamos
    На Крестах вам придется с нуля писать то, что в Питоне или Пыхе есть из коробки: работа со строками, датами, БД и пр. - то есть 90% всего бэкенда. А когда вы все это напишете и соберете в классы, чтобы удобно пользоваться - вы внезапно обнаружите, что написали все тот же Пых, только в формате велосипеда.
    Ответ написан
  • Важен ли return в main?

    gbg
    @gbg Куратор тега C++
    Любые ответы на любые вопросы
    Формально, единственная функция, в которой можно не делать return - это именно main.

    В остальных случаях, если функция что-то возвращает, наличие return обязательно - иначе будет UB.

    Почему для main исключение - никто не знает, потому что параграф в стандарте языка, на который ссылается другой параграф - потерялся:

    I looked it up. I believe this was introduced with C99, and apparently the C99 rationale is defect. It has comments for 5.1.2.2.1 Program startup, then labels the next chapter 5.1.2.3 Program execution. It should have been 5.1.2.2. As a consequence of this, the rationale for Program termination that should have been in the real chapter 5.1.2.3, has gone missing in action. Thus, main allows no return code in C99 and there exists no rational reason why.


    Источник
    Ответ написан
    Комментировать