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

    @dima20155
    you don't choose c++. It chooses you
    Вы можете повлиять на выделение памяти только посредством аллокаторов или переопределением new/delete (в специфичных случаях). Поэтому предлагаю вам посмотреть на std::basic_string и соответствующие шаблонные параметры
    Ответ написан
  • Не могу добиться вывода стека в консоль?

    @dima20155
    you don't choose c++. It chooses you
    Основная ошибка:
    std::cout << p->max[i] << "\n";  // instead of:
    // printf("%f\n", p->max[i]);


    Вот ещё пара недочетов:
    Вообще правильно
    int main() //instead of void main()

    Также странно, что 0, 1, 2 пункты меню на английском, и только 3 на русском.

    Функция isEmpty, create, del работают только со стеком, в то время как add работает ещё и с вводом-выводом, что не совсем ожидаемо, лучше вынести работу с IO из функции add, чтобы не пришлось писать ещё один add, когда захочеся пополнять стек из файла или брать данные откуда-то из сети/сокетов и т.д.. Разве что для демонстрационной программы это ок.
    Ответ написан
    Комментировать
  • Как удалить слово из строки начинающие на согласные?

    @dima20155
    you don't choose c++. It chooses you
    Создайте массив со всеми согласными. Двигайтесь по строке: когда встретили пробельный символ проверьте следующий символ. Если символ - согласная буква - слово пропускаем, если гласная, двигаясь до следующего пробельного символа сохраняем буквы в результирующую строку
    Ответ написан
  • Как узнать размер незаполненного массива в c++?

    @dima20155
    you don't choose c++. It chooses you
    Заполните изначально массив INT_MAX и затем заполните его на столько элементов, сколько нужно. Затем ищите первый элемент равный INT_MAX. Индекс этого элемента и будет длиной массива см. Как работает strlen.

    Второй и наилучший вариант - использовать std::array или написать его аналог
    Ответ написан
    5 комментариев
  • Почему доступ к элементам vector-а O(1)?

    @dima20155
    you don't choose c++. It chooses you
    То, что вы называете вектором - это связанный список, по своей сути. Вот статья навики. Слово вектор, насколько, я знаю, не используется в контексте классических структур банных. Если же под вектором имеется в виду std::vector, то данный вектор создан на основе динамического массива.
    Ответ написан
  • Может ли прерывание прервать выполнение конструктора / деструктора в С++?

    @dima20155
    you don't choose c++. It chooses you
    Что произойдет, если конструктор будет прерван?
    При возникновении исключения прерываться может любой код (кроме critical section, внутри которой отключены прерывания). Если начнется выполнение, после обработки исключения, другой задачи, а не той, которая находилась в процессе создания объекта что будет? Если это не разделяемый между задачами ресурс, то подобный код не сможет упасть.

    Важный вопрос, который вы захотите задать себе при добавлении критических секций: как часто будут отключаться прерывания? Как изменится отклик системы (особенно, если это система жёсткого реального времени)? Критическими секциями пользуются для изменения, например, мьютексов, поскольку они априори разделяемый ресурс и вызовут ошибку (например, дедлок) без подобной синхронизации. То есть если ваш объект представляет собой разделяемый ресурс, причем именно до момента создания (например, указатель на объект и процесс выделения памяти и создания объекта разделены во времени и могут быть прерваны) в таком случае синхронизация обязательна, но это исключительная ситуация, которую можно просто оборачивать в мьютексы, а не критические секции. Также хорошей практикой будет подготовить все, что возможно в момент инициализации, когда устройство ещё не приступило к работе и отклик системы не имеет значение

    P.S. примеры основаны концепциях и понятиях систем реального времени лишь для удобства.
    Ответ написан
    Комментировать
  • Можно ли выделить память определенного размера?

    @dima20155
    you don't choose c++. It chooses you
    Вы можете использовать только так:
    typedef struct {
      int a;
      char buf [10];
    }

    То есть размер должен быть известен на момент компиляции.
    В ином случае вы можете написать аллокацию памяти для buf самостоятельно.
    То есть аллоцировать кусок памяти и отдать его в конструктор структуры. А в конструкторе структуры разместить массив в куске памяти, который был аллоцирован ранее с каким-то отступом.

    Вопрос зачем это вам нужно. Если это вопрос сериализации, то используйте готовое решение.
    Ответ написан
  • Как сделать static struct in static class (C++)?

    @dima20155
    you don't choose c++. It chooses you
    Довольно специфичная задача, не знаю зачем вам это нужно, но все просто.
    Обратите внимание на синтаксис последних строк и на тот, который вы указали в вопросе.

    Не
    MyClass::MyStruct::parametr1;
    А
    MyClass::MyStruct.parametr1;

    https://godbolt.org/z/x68bEPzbz
    https://pastebin.com/EkuWr2hC
    Ответ написан
    Комментировать
  • Вопрос про указатели. Правильно ли я понимаю?

    @dima20155
    you don't choose c++. It chooses you
    Вы немного путаетесь с указателями.
    int name1 = 42; // - локальная переменная типа int, хранится на стеке
    int* name2; // - локальная переменная типа указатель на int. Сама переменная (! не её значение) хранится на стеке. 
    int* name3 = &name1;  // - аналогично name2, Значение переменной указывает на переменную, которая хранится на стеке
    int* name4 = new int(84);  // - аналогично name3, Значение переменной указывает на переменную, которая хранится в куче.


    Аналогично и с векторами:
    vector<int> v1; // - хранит значения переменных
    vector<int*> v2; //- хранит указатели на переменные (которые не обязаны вообще быть чем-либо инициализированы, и могут находиться в любом из 4-ех типов типов памяти)
    vector<int>* v3; // - указатель на std::vector<int> (может находиться в любом типе памяти).
    vector<int*>* v4; // - комбинация v2 и v3.


    new vector<int>; Лишь выделяет память в куче и никак не связан с типами переменных. Вот пример
    int v5 = *new int(42);

    В данном случае будет выделено место в куче, затем (в общем случае) вызван конструктор. Созданная в куче переменная будет хранить 42. Затем мы создаем переменную v5 на стеке и копируем в неё (конструктор копирования в общем случае) значение переменной из кучи. Указатель же на переменную в куче будет потерян aka memory leak.
    Вот, кстати, примерчик.
    https://godbolt.org/z/eETGh3Whb

    Динамически выделить на стеке можно с помощью _malloca(size). Но, в общем, случае делать этого не стоит и это остается уделом тех, кто очень тонко хочет оптимизировать код. std::array принимает одним из параметров шаблона размер, соотвествнно в момент компиляции размер необходимого массива известен и его можно хранить на стеке (по сути это обертка над C-array, удобная и безопастная). Подозреваю, что в случае гиганских размеров std::array есть вероятность, что он может быть расположен в куче (подтверждений и опровержений этому не нашел!).

    P.S. Да, многовато вышло.
    Ответ написан
  • Вопрос по оформлению кода C++?

    @dima20155
    you don't choose c++. It chooses you
    Я бы полистал уже готовые рекомендации по стилю. Из них можно подчеркнуть интересные вещи, которые могут сказаться даже на качестве самого ПО и потенциальных ошибках.
    Вот пример.
    https://google.github.io/styleguide/cppguide.html
    Ответ написан
    1 комментарий
  • Как решить ошибку multyply defined?

    @dima20155
    you don't choose c++. It chooses you
    Вы объявляете переменную в заголовочном файле, и ловите соответствующую ошибку.
    В заголовочном файле нужно её объявить хотя бы extern:
    extern Randomizer default_randomizer;
    А, например, в main.cpp:
    Randomizer default_randomizer(std::time(0));

    В современных плюсах есть более элегантное решение, насколько я помню для этого можно использовать inline переменные, чтобы можно было видеть их за пределами одной единицы трансляции, без дополнительных extern'ов
    Ответ написан
  • Как превратить void() в void (**)()?

    @dima20155
    you don't choose c++. It chooses you
    Запишите указатель в переменную и отдайте адресс этой переменной.
    Примерно так.
    #include <iostream>
    
    void bar(int n) {
        std::cout << (n*n) << std::endl;
    }
    
    void foo(void(**ptr)(int)) {
        (*ptr)(4);
        (*ptr)(40);
    }
    
    int main () {
        void(*c)(int);
        c = bar;
        foo(&c);
    }


    https://godbolt.org/z/heaWxPP7j
    Ответ написан
    1 комментарий
  • Почему нет доступа к приватному атрибуту?

    @dima20155
    you don't choose c++. It chooses you
    Добавлять дружественные функции/классы, довольно плохая идея с точки зрения архитектуры.
    Добавьте просто методы getCost() setCost(float) и уберите ненужных друзей.
    Если по какой-то неведомой причине хотите сохранить дружественный класс, то проверьте, что у вас правильная сигнатура функции и вы сохранили файл после последних изменений.
    Ответ написан
  • Почему msvc оптимизирует конструкторы несмотря на флаги?

    @dima20155
    you don't choose c++. It chooses you
    У microsoft какая-то муть с RVO (или это я слишком глупый), сам недавно отлавливал баг с RVO. Правда баг был в дебаггере. GDB норм все показывал, а MSVS нет.
    Попробуй отключить RVO оптимизацию /Zc:nrvo- и напиши что будет.
    Ответ написан
    3 комментария
  • Где ошибка в коде переворота двумерного массива?

    @dima20155
    you don't choose c++. It chooses you
    Что-то много у тебя лишнего в коде

    #include <iostream>
    
    using namespace std;
    
    int main() {
        int a = 0, b = 0, c = 0;
        cin >> a >> b;
        int A[a*b]; // not all compilers support this you have to make sure or use new/unique_ptr
        for (int i = 0; i < a*b; ++i) {
            cin >> A[i];
        }
    
        for (int i = 0; i < a*b / 2; ++i) {
            std::swap(A[i], A[a*b - 1 - i]);
        }
    
        for (int i = 0; i < a*b; ++i) {
            if ((i) % b == 0)
                std::cout << std::endl;
            std::cout << A[i] << " ";
        }
    }

    ссылка на поиграться
    https://godbolt.org/z/xqf6MYaMK
    Ответ написан
    Комментировать
  • Как сделать чтение информации из файла в несколько массивов?

    @dima20155
    you don't choose c++. It chooses you
    Что-то вроде этого. Чтение и запись в файл уже не составляет труда добавить.
    #include <iostream>
    #include <sstream>
    #include <vector>
    
    struct FunDataBase {
        FunDataBase& operator<<(const std::string& line) {
            std::vector<std::string> temp_arr;
            std::istringstream iss(line);
            std::string str;
            while ( getline(iss, str, splitter)) {
                temp_arr.push_back(str);
            }
            arr.push_back(temp_arr);
            // assert that number of elements is ok
            return *this;
        }
        void printDB() {
            for (auto i : arr) {
                for (auto j : i) {
                    std::cout << j << " ";
                }
                std::cout << std::endl;
            }
        }
        std::vector<std::vector<std::string>> arr;
        char splitter = ',';
    };
    
    int main() {
        // Write C++ code here
        FunDataBase f;
        std::string temp[] {"apple,Russia,50,100", "coconut,South africa,10,300"};
        f << temp[0];
        f << temp[1];
        f.printDB();
        return 0;
    }
    Ответ написан
  • Как убрать ошибки взаимодействия между классами?

    @dima20155
    you don't choose c++. It chooses you
    Нет необходимости делать публичную функцию дружественной. У вас что-то не так с заголовочными файлами, видимо
    Попробуйте вынесите using из класса
    Ответ написан
    7 комментариев
  • Для чего в C++ добавлена конструкция constructor() = default;?

    @dima20155
    you don't choose c++. It chooses you
    Если вы определяете любой конструктор (копирования, перемещения, с параметрами) в своем классе, то компилятор не будет генерировать конструктор по умолчанию. Если вы хотите, чтобы компилятор это сделал - используете данную конструкцию.
    Ответ написан
  • Как отдать строку?

    @dima20155
    you don't choose c++. It chooses you
    Если под строкой имеется в виду EffRange - тогда return его.
    Если std::string нет простого пути, так как это не имеет смысла (сложение obj+obj возвращает строку в половине случаев, а в половине obj?)
    Пишите дополнительный метод.
    Также operator+, обычно, возвращает ссылку на объект
    Ответ написан
    2 комментария