Ответы пользователя по тегу C++
  • Как узнать, по какому адресу загружена библиотека и какой её размер в байтах, что бы можно было сделать memmove?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Да, я предполагаю, что это идиотизм какой-то, но всё же, как?

    Для этого надо как минимум разобраться, что библиотека представляет собой в памяти, и понять, что это детали не уровня "C++", а уровня "ОС".
    После этого можно посмотреть на то, как загружаются ELF (или PE, или что там в твоей ОС), что такое сегменты и что такое динамические релокации. После этого уже можно будет понять, что отдельно друг от друга сегменты библиотеки двигать нет смысла (потому что относительные ссылки между ними не помечены релокациями), а всё целиком имеет смысл двигать только если после перемещения обновлять места динамических релокаций.
    Ответ написан
    Комментировать
  • Почему при каждом выполнении программы постоянно разыне результаты шифрования DES3?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    при каждом выполнении разные результаты.
    CBlocks getKeys(const std::string &key) {
        auto keys = explode_s(";", key);
        if (keys.size() < 3) {
            throw std::invalid_argument("size of keys has to be equal 3");
        }
    
        DES_cblock Key1;
        DES_cblock Key2;
        DES_cblock Key3;
        strncpy((char*) Key1, keys[0].c_str(), keys[0].size());
        strncpy((char*) Key2, keys[1].c_str(), keys[1].size());
        strncpy((char*) Key3, keys[2].c_str(), keys[2].size());
    
        return CBlocks(Key1, Key2, Key3);
    }

    так а чего удивительного, если ты неизвестно куда свои ключи в этой функции копируешь?
    Ответ написан
  • Как создать независимый процесс?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    if (a == 1) {
            CreateProcess(szFileName, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
            WaitForSingleObject(pi.hProcess, INFINITE);
            ...
        }
        ...
        return 0;

    запускается новый процесс но если его закрыть то закрывается и родитель.

    Ну так ты ровно это и написал: родитель запускает процесс и ждёт его завершения, а после этого завершается сам. Хочешь другого поведения -- пиши другое поведение.
    Ответ написан
    3 комментария
  • Как прочитать заголовок PCAP пакета c/c++?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    IP адреса Source и Destination выводятся одинаковыми

    Из man inet_ntoa:

    The string is returned in a statically allocated buffer,
    which subsequent calls will overwrite.


    С вот таким изменением твой код у меня работает как ожидалось:
    printf("src address: %s ",  inet_ntoa(ip->ip_src));
    printf("dest address: %s\n",  inet_ntoa(ip->ip_dst));


    Подозреваю, что совсем левые IP могут лезть из не-IP кадров. Проверяй поле протокола в ethernet заголовке перед тем как начинать разбор IP-заголовка.
    Ответ написан
  • Почему "идентификатор не определён"?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Потому что p, p1 и p2 -- локальные для блока if (flak == 0), и за его пределами не существуют.
    См.
    Ответ написан
    Комментировать
  • Алгоритм поворота динамического массива без доп памяти?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как можно реализовать, поворот динамического массива (матрица), без доп памяти?

    Как-то так:

    #include <stddef.h>
    #include <stdio.h>
    
    typedef int T;
    
    void rotate(T *p, size_t m, size_t n, size_t (*turn)(size_t m, size_t n, size_t idx))
    {
            size_t i, j, k;
    
            for (i = 0; i < m * n; ++i) {
                    T tmp0, tmp1;
    
                    for (j = 0; j < i; ++j) {
                            for (k = turn(m, n, j); k != i && k != j; k = turn(m, n, k)) {
                            }
                            if (k == i)
                                    break;
                    }
                    if (j < i)
                            continue;
    
                    tmp0 = p[i];
                    for (j = turn(m, n, i); ; j = turn(m, n, j)) {
                            tmp1 = p[j];
                            p[j] = tmp0;
                            tmp0 = tmp1;
                            if (j == i)
                                    break;
                    }
            }
    }
    
    void dump(size_t m, size_t n, T p[m][n])
    {
            size_t i, j;
    
            for (i = 0; i < m; ++i)
                    for (j = 0; j < n; ++j)
                            printf("%d%s", p[i][j], j == n - 1 ? "\n" : ", ");
    }
    
    size_t turn_ccw(size_t m, size_t n, size_t idx)
    {
            return (n - 1 - idx % n) * m + (idx / n);
    }
    
    size_t turn_cw(size_t m, size_t n, size_t idx)
    {
            return (idx % n) * m + m - 1 - (idx / n);
    }
    
    #define M 5
    #define N 7
    
    int main()
    {
            size_t i, j;
            T a[M][N];
    
            for (i = 0; i < M; ++i)
                    for (j = 0; j < N; ++j)
                            a[i][j] = i * N + j;
    
            rotate(&a[0][0], M, N, turn_ccw);
            dump(N, M, (T (*)[M])&a[0][0]);
            printf("\n");
            rotate(&a[0][0], N, M, turn_cw);
            dump(M, N, (T (*)[N])&a[0][0]);
    }


    turn преобразует линейный индекс элемента из оригинального массива в индекс элемента в повёрнутом массиве.
    Цикл по i переставляет цепочки элементов отображающихся друг в друга с началом в элементе i. Первый цикл по j проверяет, не был ли элемент i уже переставлен в составе более ранней цепочки. Второй цикл по j переставляет одну цепочку.
    Ответ написан
    Комментировать
  • Почему и как этот код на Си работает, если он работать не должен?

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

    int i,k,w = 0;

    Сюрприз №1: в этой строке мы занулили только w (да и то непонятно зачем).

    // каким образом i учавствует в коде, если мы с ней
    // ничего не делали?? если убрать это условие, код не работает

    for(i=0; i<w; i++)

    Сюрприз №2: вот же, i++, какое "ничего"?

    зачем в этом коде нужна переменная k,

    Переменная k в этом коде не нужна, если не считать единственного printf с её участием.

    Как это код работает?

    Разбивает исходную строку по пробелам тут: ptr=strtok(s," ");, в цикле for(i=0; i<w; i++) проверяет, что подстрока состоит только из символов 'a'..'z', если да (т.е. i в цикле достиг длины текущей подстроки) -- печатает подстроку. Переходит к следующей подстроке тут: ptr=strtok(NULL," ");
    Ответ написан
  • C++ Builder. Аналог REG DELETE в CMD. Как удалить ветку реестра?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    AnsiString params[] = {"/c REG DELETE \"***\"};
            for (unsigned short i = 0; i < params->Length(); {
               system(params[i].c_str());
            }

    ругается на "Access violation at address"

    Потому что этот код думает, что длина первой строки -- это количество строк в массиве params. С чего бы?
    Ответ написан
    Комментировать
  • Как правильно решить задачу на работу с двумя массивами в asm?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Нужно из c++ переместить этот массив в ассемблерную вставку, а там уже перенести из этого массива в другой массив все элементы, которые равны сумме соседних.
    То есть регистры e*x нельзя брать. Кто может подсказать, где найти материал по этой теме, либо же предложить пример кода для решения поставленной задачи?

    Можно написать этот код так, что он не будет использовать никакие конкретные регистры явно. Конкретные регистры будут подставлены компилятором. Например (gcc):
    #include <stdint.h>
    
    void f(void)
    {
        uint32_t a[16] = {1, 2, 3, 1, 5, 4, -1, }, b[16] = {0};
        void *a1, *b1;
        uint32_t tmp, cnt = 14;
    
        asm (
            "lea %[a], %[a1]\n\t"
            "lea %[b], %[b1]\n"
            "1:\n\t"
            "mov (%[a1]), %[tmp]\n\t"
            "add 8(%[a1]), %[tmp]\n\t"
            "cmp 4(%[a1]), %[tmp]\n\t"
            "jne 2f\n\t"
            "mov %[tmp], (%[b1])\n\t"
            "add $4, %[b1]\n"
            "2:\n\t"
            "add $4, %[a1]\n\t"
            "dec %[cnt]\n\t"
            "jnz 1b\n\t"
            : [cnt] "=&r" (cnt), [tmp] "=&r" (tmp),
              [a1] "=&r" (a1), [b1] "=&r" (b1),
              [b] "=m" (b)
            : [a] "m" (a));
    }
    Ответ написан
  • Как вывести несколько MessageBox на C++?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    MessageBox -- модальный. Невозможно одновременно вывести несколько MessageBox из одного потока. Можно создать несколько потоков и в каждом из них вызвать MessageBox.
    Ответ написан
    Комментировать
  • Почему не идентифицируется переменная NAN?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Предположу, что NAN появился в С++11, а VS12 его, вероятно, не поддерживает.
    Ну и, справдливости ради, определятся он в <cmath>, который неплохо было бы явно подключить.
    Ответ написан
    1 комментарий
  • Merge c типом string?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    if (arr[i] <= arr[j]) {
                d[k] = arr[i];
                da[k] = arr2[i];
                i++;
            } 
            else {
                d[k] = arr[j];
                da[k] = arr2[i];
                j++;
            }

    Тут какая-то совсем уж беда с индексами arr и arr2.

    std::string d[end - begin];
        std::string da[end - begin];


    А тут беда с размерностями, при обращении к этим массивам вышеприведённым кодом будут выходы за пределы.
    Ответ написан
    Комментировать
  • Как определить приоритет потока?

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

    Повышение приоритета не ускорит работу потока который занимается вычислениями, но понизит отзывчивость всех остальных потоков.
    Чтобы ускорить нужно сначала понять что именно тормозит, а чтобы это понять нужно профилировать.
    А уж когда станет понятно -- тогда и думать, что делать -- менять алгоритм, распараллеливать, использовать SIMD или что-нибудь ещё.
    Ответ написан
    3 комментария
  • Как правильно добавить в программу считывание количества объектов класса с помощью статического поля?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    постоянно 0 показывает

    Потому что в одном конструкторе ты matr::m_id инициализировал, а в другом -- нет.
    Ответ написан
  • Как передать указатель на двухмерный массив?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    https://toster.ru/answer?answer_id=513953#answers_... , за исключением части касающейся С99.
    Ответ написан
  • Наследование. Каким образом вызывается operator=() через оператор разрешения контекста?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Ведь operator=() - не статический метод, а значит его вызывать можно только через объект.

    Если делать это внутри другого не-статического метода, то можно, объектом будет *this.
    Ответ написан
    1 комментарий
  • Я человек не очень понимающий. Скажите пожалуйста что я не так сделал ( программа вылетает при работе)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    что я не так сделал?

    Как минимум вот это:
    double** a = new double *[n];
      int min;
      for (int k = 0; k < n; ++k)
      {
        for (int j = 0; j < n; ++j)
        {
          cout << "Enter element:";
          cin >> &a[k][j]);
        }
      }

    Ты представил матрицу как массив указателей на строки, выделил память под этот массив, но не выделил память под сами строки.
    Ответ написан
  • Как запустить приложение через forkpty?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    может быть так?

    #include <pty.h>
    #include <unistd.h>
    #include <thread>
    #include <future>
    #include <iostream>
    #include <string>
    
    ssize_t sz = 1;
    
    int main()
    {
      int mfd;
    
      pid_t pid_fork = forkpty(&mfd, NULL, NULL, NULL);
    
      if (!pid_fork) {
        // Дочерний процесс
        execl("/bin/sh", "-", NULL);
      } else {
        // Родительский процесс
        char buf[1024];
    
        // Async
        auto future = std::async(std::launch::async, [mfd]() {
          std::string line;
          while (sz) {
            std::getline(std::cin, line);
            line = line  + "\n";
            write(mfd, line.c_str(), line.size()); // Нужно направить в дочерний процесс как stdin
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
          }
        });
    
        while (sz = read(mfd, buf, sizeof(buf))) {
          write(STDOUT_FILENO, buf, sz); // Вывод из дочернего процесса stdout
          std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
    
        exit(0);
      }
    }

    Поскольку это теперь терминал, то имеет смысл установить размеры pty такими же, как у терминала вызывающей программы, например так:

    ...
    #include <sys/ioctl.h>
    ...
      struct winsize ws, *pws = NULL;
    
      if (ioctl(1, TIOCGWINSZ, &ws) >= 0)
        pws = &ws;
      pid_t pid_fork = forkpty(&mfd, NULL, NULL, pws);


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

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    как быть? Какой размер массива объявить?

    Не объявляй никакой. Воспользуйся вместо этого стандартным контейнером, например std::vector.
    Но если хочется помучаться -- воспользуйся указателем и выделяй память динамически, по мере поступления входных данных.
    Ответ написан
    Комментировать
  • Множественный вызов конструктора базового класса при виртуальном наследовании?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    напрашивается вопрос "Будет ли конструктор базового класса A вызываться два раза, ведь в конструкторе C тоже вызывается конструктор A?".


    Нет, не будет, потому что нет, при конструировании объекта класса D конструктор A из конструктора C не вызывается. См.:
    A mem-initializer where the mem-initializer-id denotes a virtual base class is ignored during execution of a constructor of any class that is not the most derived class.
    Ответ написан
    Комментировать