Ответы пользователя по тегу C++
  • Как исправить ошибку сегментации C++ (segmentation fault)?

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

    Одна очевидная ошибка - вы не уменьшаете n при удалении элемента. И тогда на следующей итерации вы будете что-то делать с элементом за концом массива.

    Еще одна ошибка у вас в том, что вы в add, например, всегда удаляете указатель на f. А в самом начале этот указатель неинициализирован. Удаление такого случайного указателя - это undefined behavior. Программа может упасть сразу, а может только на следующей итерации цикла.

    Советую инициализировать f в nullptr и перед удалением всегда проверять, что удаяемый казатель не нулевой.
    Ответ написан
    2 комментария
  • Почему вызов метода класса гораздо медленее вызова обычной функции и как это исправить?

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

    Правильнее добавить в тестируемую функцию какую-то работу. Тогда вы будуте действительно сравнивать вызов функции и метода. Или отключить всю оптимизацию.
    Ответ написан
    2 комментария
  • Зачем нужен амперсанд перед именем функции/метода?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    На самом деле понятнее писать вот так:
    int& Foo();

    Функция возвращает ссылку на int. Ссылка - это как указатель, только она не может указывать вникуда. Соответственно, вы не можете завести переменную ссылку сразу не инициализировав ее - а на что она будет указывать. И также ссылки, в отличии от указателей, не надо ее разыменовывать.

    Использовать можно, например, вот так:
    int& ref = Foo();
    std::cout << ref+10;


    Тут под переменную ref не выделяется память, ведь это ссылка, которая инициализируется тем, что вернула Foo. Так же сам объект не копируется. Максимум, под капотом скопируется адрес.
    Поэтому ссылки имеет смысл заводить на тяжелые объекты, чтобы не копировать их зря и не выделять память.

    Так же можно через эту возвращенную ссылку изменять основной объект:
    int x;
    int& Foo() {
        return x;
    }
    ...
    
    x = 0;
    int& ref = Foo();
    ref = 10;
    std::cout << x:

    Этот код выведет 10.

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

    Ну и еще, можно с этой возвращенной ссылкой работать и как с обычным int:
    int x = 2 + Foo();
    Но если вы не собираетесь менять значение внутри или не пытаетесь сэкономить на копировании объекта, то вам нет смысла вообще ссылки использовать.

    Ну и, конечно, аккуратно со ссылками надо быть. Вполне можно извернуться и получить ссылку указывающую на удаленную память. Напрямую ссылки на локальные переменные компилятор возвращать не дает, но если сначала взять адрес в указатель, а потом его разименовать и вернуть как ссылку, то вы получите undefined behavior.
    Ответ написан
    1 комментарий
  • В чем отличия между кодами?

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

    Вам надо использовать s.substr.
    Ответ написан
    Комментировать
  • Как оформить список C++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Используйте snprintf. Так можно с тем же форматом вывести все данные не в консоль, а в строку.
    Ответ написан
  • Как определить тип функции для шаблона?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Можно использовать typedef int value_type; в классе с Setter/Getter.

    Тогда в вашем шаблоне вы можете использовать C::value_type. Так в STL, например, сделано.

    Плюсы: не надо обязательно заводить n. Можно обзывать его как удобнее или оно может вообще иметь другой тип, если свойство хранится неявно.

    Минусы: Надо обязательно заводить этот самый value_type и обновлять его вместе с методами Getter/Setter.
    Ответ написан
  • Сдвиг двумерного массива, появление ошибки Stack around the variable 'arr' was corrupted. Как исправить без переписывания кода?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Код исправляется элементарно. Надо внутренний цикл по j гнать не до 0, а до 1. Что бы не вылезать за границу массива, вы же там к j-1 -ому элементу обращаетесь. А поскольку вы делаете swap, то вы меняете элементы массива с памятью перед ним. Массив - локальная переменая, а значит он лежит на стеке и вот это вот затирание памяти рядом с массивом и есть это самое "Stack around the variable 'arr' was corrupted".

    Ну и по стилю - вместо i > -1 обычно пишут i >= 0.
    Ответ написан
    Комментировать
  • Как решить задачу с символами? Почему не работает одна функция?

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

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Я так понимаю, у вас проблема со строчкой
    aobj1[0] = a(2);

    Тут вызывается конструктор для временного значения a. Потом оператор копирования из временной переменной в *aobj. Потом вызывается деструктор временного значения.

    А потом где-то в конце произойдет и деструктор aobj.

    У aobj delete_counter после этой строчки равен 1 (ведь он скопирован у временного значения, которое сделало delete_counter единицей в констукторе). В конце при вызове деструктора aobj там delete_counter будет 1 в начале.

    Вы смотрите на адрес this в дебагере в деструкторе. Два вызваных деструктора будут для двух разных объектов (для временного значения и для aobj).

    Если вы хотите какой-то счетчик ссылок делать, то вам надо переопределять операторы копирования и перемещения (а так же все возможные конструкторы). И там аккуратно изменять счетчик ссылок. И счетчик ссылок должен быть частью общего объекта - частью класса b, а не класса a.
    Ответ написан
    4 комментария
  • Почему простой цикл на c++ выполняется медленнее, чем на golang?

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

    Чтобы этого не было, можно ксорить не с константой, а с индексом i, например.
    Ответ написан
    Комментировать
  • Как объявить функцию в другой функции?

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

    Перед F напишите
    int G(int n);

    Это скажет компилятору, что есть вот такая функция. Ее определение же остается также дальше по тексту после F.
    Ответ написан
    Комментировать
  • Есть ли смысл в уточнении типов данных чисел? И что это даст?

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

    Оптимизировать же переменные смысла нет никакого. Сэкономите пару байт буквально.
    Ответ написан
    Комментировать
  • У меня несколько ошибок "was not declared in this scope" в коде C++, что делать?

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

    И так по каждой ошибке от компилятора в вашем вопросе. Смотрите на какое имя он ругается и где эта функция/переменная определена.
    Ответ написан
    1 комментарий
  • Как правильно применить абстрактный класc здесь?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Пометьте все методы DVector(2) в Vector2.h override. Посмотрите на ошибки компилятора.
    Ответ написан
    4 комментария
  • Реализация обоюдного включения файлов проекта?

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

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

    Ну и Include guard'ы используйте
    Ответ написан
    Комментировать
  • Почему не работает с char[]?

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

    Это же c++, судя по тегам? Сделайте тогда все поля структуры static const и не заводите ее экземпляр. Обращайтесь к константам так: MqttConfig::host. Константы обычно задают так, а не значениями по умолчанию полей структуры.

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    В родительском классе у вас DVector(2P), а в наследнике DVector(2).

    Несовподают типы, об этом вам компилятор и говорит.
    Ответ написан
  • Как исправить ошибку Memory limit?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Ошибка в функции check. Вам тогда надо проверять, что текущее расстояние до ii, jj меньше или равно расстояния до i,j +1. Чтобы вы возвращали 0, если нет смысла переписывать расстояние и добавлять вершину в очередь.

    Из-за этого у вас каждая вершина может быть в очереди кучу раз.

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

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    f(std::string("abc"))

    Каких-то специальных встроенных в язык средств созадавать const std::string нету.
    Ответ написан
    2 комментария