Ответы пользователя по тегу C++
  • Можно ли передать в функцию-предикат значение как в лямбду?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как в этом случае заставить функцию GreatherThanN увидеть это самое N?

    Если функции нужен контекст, то вместо функции можно использовать функциональный объект -- объект класса с оператором ():

    class GreaterThanN {
        int N;
    public:
        GreaterThanN(int _N): N(_N)
        {
        }
        bool operator ()(int x) const
        {
            if (x > N)
                return true;
            return false;
        }
    };
    
    int N = 5;
    count_if(begin(v), end(v), GreatherThanN(N));
    Ответ написан
    3 комментария
  • Сколько будут занимать места параметры в данном случае?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    ума не приложу, почему размер void _stdcall foo(short a, short b); параметров равен 8

    Потому что аргументы размером меньше 4 байт расширяются до 4 байт. См.

    Как выяснилось, стек растет не только на 4 байта, а на 2.

    То, что в стек физически можно положить 2 байта (а можно ведь и 1, и 3 -- sub $imm, %esp) не означает, что это следует делать. См:
    The stack will always be maintained 16-byte aligned, except within
    the prolog (for example, after the return address is pushed), and except where
    indicated in Function Types for a certain class of frame functions
    Для венды на x86 я такого описания на том же сайте не нашёл, но точно выравнивание должно быть не меньше 4.
    Ответ написан
    Комментировать
  • Зачем нужно выравнивание памяти по слову?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Я не знаю, можно ли такого уровня детали найти для современных процессоров, а вот для i80386 в спецификации, в разделе 5.3.6 легко можно видеть, что невыравненный доступ к памяти занимает два цикла, вместо одного.
    За пределами мира x86 многие процессоры вообще не поддерживают доступ к невыравненным данным на аппаратном уровне.
    Ответ написан
    Комментировать
  • C++ что надо учить чтоб уметь создавать оконные програмы?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    что надо учить чтоб уметь создавать оконные програмы?

    Конечные автоматы. После этого -- немного многопоточности. После этого не составит труда разобраться и использовать любой GUI API.
    Ответ написан
    Комментировать
  • Wchar_t в параметрах функции main?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему не отобразился текст параметра? Тип же верен.

    Потому что недостаточно просто поменять тип параметра функции. Нужно ещё поменять то как она вызывается.
    В венде для этого есть другое имя для main -- wmain.
    Ответ написан
    5 комментариев
  • Почему не открывается сокет для прослушивания?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Обёртка говорит, что все успешно, присваивается sockfd = 0,

    Это очень подозрительно, потому что 0 -- это обычно файловый дескриптор стандартного ввода.
    Ответ написан
  • Как узнать что данные отправлены по uart?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как проверить что данные ушли?

    Я бы смотрел в сторону fsync с файловым дескриптором последовательного порта.
    Ответ написан
    Комментировать
  • Как редактировать код страницы в браузере при её загрузке?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как редактировать код страницы в браузере при её загрузке?

    Зависит от браузера. В FF для этого есть greasemonkey -- можно писать скрипт на JS, который будет выполняться после загрузки страницы.
    Ответ написан
    Комментировать
  • Как сложить два числа, которые ввели с помощью cin через пробел?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как сложить два числа

    Оператором +.

    Например, я ввожу 2 6, через пробел
    результат должен быть 8

    Если эту программу откомпилировать, запустить и ввести 2 6, то она выводит 8.
    В чём проблема?
    Ответ написан
  • Почему не компилируется SFML приложение?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    g++ -o app.exe "src\\log.o" "src\\app.o"

    надо добавить что-то типа -lsfml-graphics -lsfml-window -lsfml-system в конец.
    См. https://www.sfml-dev.org/tutorials/2.5/start-linux.php
    Ответ написан
    2 комментария
  • Почему появляется ошибка segmentation fault но при повторном запуске программы её нет?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Я не вижу криминала который мог бы привести к segfault в приведённой программе.
    Почему поведение может отличаться между запусками -- например потому что запись в файл /sys/class/gpio/export меняет состояние системы и запоминается между запусками.
    Кроме того, согласно https://www.kernel.org/doc/Documentation/gpio/sysfs.txt в direction надо писать in или out, а high или low нужно писать в value. Сегфолта от этого быть не должно, тем не менее.

    Что происходит, если собрать программу с отладочной информацией и запустить так, чтобы она упала под отладчиком?

    UPD: посмотрел ещё немного... В приведённом исходном тексте кривые юникодные кавычки. Рекомендую исправить на ASCII, либо вставить исходный текст как есть, без фокусов.
    Ответ написан
  • Вылет при удалении динамического массива?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    char *s = new char[strlen(source) + 1];
    ...
    strcpy_s(s, strlen(s), source);


    strlen(s) -- вообще за гранью добра и зла и возвращает случайное число, по большому счёту. Потому что s -- только что выделенный неинициализированный массив.

    Вызов strcpy_s совершенно бессмысленный и неправильный. Бессмысленный, потому что ты только что выделил столько памяти, сколько данных в строке. strcpy_s имеет смысл, если буфер в который ты копируешь -- это массив фиксированной длины. Неправильный, потому что даже если ты имел в виду strlen(source), а не strlen(s), то должен был передать strlen(source) + 1, чтобы было куда 0-терминатор скопировать. Кроме всего прочего, strcpy_s ещё и возвращает код ошибки, который имеет смысл проверить.

    Лучше всего в этом месте было бы вызвать memcpy(s, source, strlen(source) + 1); или вообще выкинуть s = new char [...]; strcpy_s ... delete [] s; и заменить на s = strdup(source); ... free(s);
    Если очень хочется strcpy_s, то хотя бы так: strcpy_s(s, strlen(source) + 1, source);

    Исправление этого места починит и delete, потому что delete валится из-за того, что ты поломал heap.
    Ответ написан
    1 комментарий
  • Как исправить ошибку в коде c++?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Замени head = malloc(sizeof(struct Node)) на head = new Node.
    Потому что malloc тебе конструктор std::string внутри data_list не вызовет.
    И не вставляй код картинками.
    Ответ написан
    Комментировать
  • Где найти актуальную версию arm тулчейна?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Видишь ли в чём дело, если ты используешь тулчейн сильно отличный от того, которым собраны библиотеки установленные на устройство, у тебя есть три варианта действий:
    - перестроить и обновить все библиотеки на устройстве.
    - создать отдельную иерархию каталогов /lib, /usr/lib, ... в которые сложить библиотеки (.so) нового тулчейна и тем или иным способом заставить исполняемые файлы собранные новым тулчейном использовать их.
    - линковать свои исполняемые файлы статически.

    В последнем варианте тебе подойдёт почти любой тулчейн, два других варианта -- более замороченные.

    https://elinux.org/Toolchains#Prebuilt_toolchains
    Ответ написан
    Комментировать
  • Преобразование char в const char*?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Имеется строка
    string message = "Hello!";
    Функция принимает const char*, мне нужно передать в неё первый символ этой строки.


    void f(const char *);
    
    string message = "Hello!";
    string message1(1, message[0]);
    f(message1.c_str());
    Ответ написан
  • Как передать значение переменной в стек (Ассемблер)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Код может выглядеть как-то так:

    void OutFloat(double v);

    sub sp,16
    mov bp,sp
    fstp qword ptr [bp + 8]
    call OutFloat
    add sp,16


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

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Она работает и выводит в консоль "destruct". Но после этого объект никуда не исчезает.

    Тебе предстоит узнать много нового. О том, что такое неопределённое поведение. О том, что удалять опреатором delete можно только объекты созданные оператором new. О том, что обращение к полям объекта после вызова деструктора -- это неопределённое поведение, так же как и вызов деструктора больше чем один раз. О том, что это забота программиста -- следовать правилам языка, а рантайм может закрывать глаза на ошибки, а может громко кричать и завершать программу при первой же возможности.

    Она работает и выводит в консоль "destruct". Но после этого объект никуда не исчезает. К нему по прежнему можно обратиться и вывести значения xy. При этом по завершению работы программы, в консоль выводится "destruct" второй раз.

    Ну а у меня твоя программа ожидаемо вылетает сразу же в месте вызова delete.

    как правильно уничтожить объект?

    Объект на стеке можно корректно уничтожить двумя способами: естественным -- выйдя из блока в котором он определён, и насильственным -- вызвав явно его деструктор и создав на его месте другой объект.
    Ответ написан
  • Как получить доступ к private полям без friend-функций?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Непонятно, в каких отношениях состоят List и Node.

    По-правильному, все поля класса должны быть приватными.

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

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    bool& operator [] (int index) {
        return selfVector[index];
      }

    должен стать
    std::vector<bool>::reference operator [] (int index) {
        return selfVector[index];
      }
    Ответ написан
    Комментировать
  • Компиляция c++?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    получается mainx узнает о том что есть функция printx() на этапе линковки [mainx.o] и [printx.o]?

    Да.

    Каким образом происходит передача информации в [mainx] что функция printx() существует?

    Это работа линковщика связывать ссылки на неопределённые символы с определениями этих символов.
    В main.o в месте вызова printx ставится команда вызова, в секции символов заводится неопределённый символ printx а в секции релокаций заводится запись, связывающая команду вызова с символом:

    objdump -dr mainx.o
    ...
    0000000000000000 <main>:
       0:   55                      push   %rbp
    ...
      3a:   89 c7                   mov    %eax,%edi
      3c:   e8 00 00 00 00          callq  41 <main+0x41>
                            3d: R_X86_64_PLT32      _Z6printxi-0x4
      41:   b8 00 00 00 00          mov    $0x0,%eax
      46:   c9                      leaveq 
      47:   c3                      retq   
    ...


    readelf -a mainx.o
    ...
    Relocation section '.rela.text' at offset 0x580 contains 12 entries:
      Offset          Info           Type           Sym. Value    Sym. Name + Addend
    ...
    00000000003d  001400000004 R_X86_64_PLT32    0000000000000000 _Z6printxi - 4
    ...
    
    Symbol table '.symtab' contains 25 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
    ...
        20: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _Z6printxi
    ...


    В printx.o в секции символов заводится символ, ассоциированный с адресом в коде, где определена функция printx:

    readelf -a printx.cpp
    ...
    Symbol table '.symtab' contains 24 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
    ...
        14: 0000000000000000    75 FUNC    GLOBAL DEFAULT    1 _Z6printxi
    ...

    Здесь value == 0 -- потому что printx оказалась по адресу 0 в секции .text.

    Линковщик объединяет входные секции согласно скрипту линковки, после чего вставляет конечные адреса символов в места, которые ссылаются на них.
    Ответ написан
    Комментировать