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

    15432
    @15432
    Системный программист ^_^
    Функции на c++ по большей части имеют фиксированное число параметров, так что с определением числа параметров нет проблем - это известно на этапе компиляции.
    Функции с переменным числом параметров (например, printf(char* format, ...) )имеют свой механизм определения числа параметров, который вы сами должны закодить на ваше усмотрение. Можете первым аргументом подавать общее число аргументов, как и предлагаете.
    Ответ написан
    Комментировать
  • Получить метод запаковки/распаковки файла?

    15432
    @15432
    Системный программист ^_^
    Приложите пример файла, может узнаю алгоритм.
    Если нет самого запаковщика - смотреть содержимое. В заголовке может содержаться подсказка. А так, определить произвольный алгоритм запаковки очень затруднительно.
    Ответ написан
    9 комментариев
  • Почему выводит крякозябры?

    15432
    @15432
    Системный программист ^_^
    В операторе = вы копируете указатель, память по которому может быть очищена в будущем.
    Нужно выделять память и копировать данные
    Ответ написан
  • Как освободить память сразу всем полям структуры?

    15432
    @15432
    Системный программист ^_^
    Написать конструктор и деструктор для структуры?

    struct BUFF
    {
        int * a;
        int * b;
        int * ...;
        BUFF();
        ~BUFF();
    };
    
    BUFF::BUFF()
    {
        a = new int[32];
        b = new int[32];
        .... = new int[32];
    
    }
    
    BUFF::~BUFF()
    {
        delete[] a;
        delete[] b;
        delete[] ...;
    }


    Если принципиально, можно создать массив из указателей
    struct BUFF
    {
        int * abc[3];
    };

    и в цикле их создавать / удалять
    for (int i = 0; i < 3; ++i)
    {
        delete[] buff.abc[i];
    }
    Ответ написан
    5 комментариев
  • Почему возникает ошибка LNK2001 Неразрешенный внешний символ символ?

    15432
    @15432
    Системный программист ^_^
    extern MyType X
    эта строка означает, что переменная с именем X типа MyType уже существует и объявлена в некотором другом .cpp файле, причем глобально.

    TL;DR: уберите extern
    Ответ написан
    Комментировать
  • Можно как-нибудь посмотреть, во что разворачиваются шаблоны при компиляции?

    15432
    @15432
    Системный программист ^_^
    IDA в руки и вперёд. А вообще, для каждого используемого типа в шаблоне, создается отдельная функция и подставляется в места вызова.
    Ответ написан
  • Могу присвоить значение не существующему элементу массива и вывести его, в чем проблема?

    15432
    @15432
    Системный программист ^_^
    Нет, просто вы записали в область памяти за пределами места, выделенного под массив. Это называется buffer overflow и может привести к непредсказуемым последствиям - например, если сразу за массивом выделена другая важная переменная, она может быть перезаписана. Отсутствие проверки ввода пользователя на допустимые границы может быть серьёзной уязвимостью безопасности - локальные переменные выделяются на стеке, в том числе и массивы. Выход за пределы массива позволит перезаписать адрес возврата (который тоже расположен на стеке) и в теории выполнить произвольный код.

    С целью предотвращения такого поведения в языках более высокого уровня при каждом присваивании проверяются границы доступной памяти, не позволяя "выстрелить себе в ногу". В C++ такого нет в угоду большей производительности.
    Ответ написан
    3 комментария
  • Что происходит с указателем?

    15432
    @15432
    Системный программист ^_^
    Возможно, getUser находится в библиотеке, и у студии просто возникли проблемы с отладкой либы. (например, символов нет). Возвращается нормальный объект User?

    Ну или такой экзотический вариант как Engine e объявлена локально и самоуничтожилась до вызова getUser, удалив заодно и Account внутри себя. (попробуйте Engine через new создать)
    Ответ написан
  • TCP: правда ли, что send/write нельзя вызывать из разных потоков, иначе перепутается содержимое буферов?

    15432
    @15432
    Системный программист ^_^
    На коротких сообщениях (меньше MTU) такого не будет. Вот если будете в одном из потоков слать несколько килобайт, может возникнуть ситуация, когда части сообщений перемешаются.
    Пример:
    - поток 1 посылает 10000 байт, send вернул 2048
    - поток 2 в это время записывает короткую команду в этот же сокет
    - поток 1 досылает оставшиеся байты, но перед ними уже влезла команда из потока 2

    Почему бы не добавить мьютексы? Или несколько сокетов?
    Ответ написан
    5 комментариев
  • GetModuleFileNameA, в чем проблема?

    15432
    @15432
    Системный программист ^_^
    GetModuleFileNameA это ASCII версия функции. В свойствах Release у вас может быть указано использование Unicode, там требуется GetModuleFileNameW версия функции. А вообще GetModuleFileName без A или W используйте.

    И да, strlen нужно использовать после вызова GetModuleFileName. И опять же, нужно TCHAR версию _tcslen использовать для совместимости с юникодом
    Ответ написан
    Комментировать
  • Как пользоваться утилитой res2h для переноса ресурсов в статические массивы?

    15432
    @15432
    Системный программист ^_^
    1. Поместите в папку ваш файл для конвертации и программу res2h
    fde6bf9f4a084537b9e1e64b1bd20265.jpg
    2. Откройте командную строку (клик правой кнопкой мыши с удержанием Shift -> открыть окно команд)
    41f3e3e92ece4b118af8d2183df14f4a.jpg
    3. Выполните конвертацию командой res2h.exe file_to_convert.ext output_file.cpp -c
    53e92d33752540a7ad63bd8a8a8243d8.jpg
    4. Готово
    ea9f467bef7a4b83801f7f14efa76162.jpg
    Ответ написан
    5 комментариев
  • В чём различие между i++ и i+1, когда речь идёт в о массивах?

    15432
    @15432
    Системный программист ^_^
    А давайте я укажу на все ошибки в вашей программе?

    1) for(int i = 1 ...)
    Самое бросающееся в глаза. Индексация массивов начинается с нуля. Соответственно, условие в цикле должно быть
    for(int i = 0; i < N; ++i)
    (И не придется заводить массив на N+1 элементов)

    2) exit(0)
    Любая ваша проверка сразу же приведет к завершению программы. Поэтому ваша программа изначально работает некорректно - происходит сравнение только двух первых элементов

    3) пресловутый i++
    Рассмотрим полную команду
    if (p[i] < p[i++])
    По приоритетам, первой выполнится "i++", после чего значение i увеличится на единицу, в результате чего итоговое сравнение будет эквивалентно
    i += 1;
    if (p[i] < p[i]) ...
    Более того, даже если не учитывать неправильное сравнение и выход в первой же проверке, за один цикл for значение i оказывается увеличенным дважды (i++ в конце цикла и i++ в условии), что тоже далеко не нормально.

    4) мелочи вроде
    -printf(\n);
    вместо того, чтобы дописать \n в конец прошлого текста
    -использование short, когда эффективнее использовать int

    В общем, тренируйтесь, познавайте принцип работы команд, совершенствуйте знание языка и впредь старайтесь избегать подобных ошибок :)

    как можно быстро исправить эту программу:

    int main()
    {
      setlocale(LC_ALL, "RUSSIAN");
      int i;
      int p[N];
      for (i = 0; i < N; ++i) //вводим все числа
      {
        printf("\n Введите элемент массива p[i] = ");
        scanf_s("%d", &p[i]);
      }
    
      for (i = 0; i < N; ++i) //печатаем, что ввели - для проверки
        printf("%5d ", p[i]);
    
      for (i = 0; i < N - 1; ++i) //проходимся по всем числам до предпоследнего
      { //потому что последнее не с чем сравнивать, за ним дальше чисел нет
        if (p[i] >= p[i+1]) //проверяем только случай, когда условие возрастания не выполняется
        {
          printf("\n Элементы массива - НЕ возрастающая последовательность\n");
          exit(0); //сразу же выходим из программы, т.к. определили невозрастание
        } //иначе продолжаем сравнивать элементы!
      }
    //мы до сих пор не вышли из программы, значит, последовательность всё же возрастающая
      printf("\n Элементы массива - возрастающая последовательность");
    }
    Ответ написан
    9 комментариев
  • OpenMP проверка четности потока, как?

    15432
    @15432
    Системный программист ^_^
    1) ваши for (i = thread;i < threads;i += threads) ничего не делают и эквивалентны int i = thread;
    2) когда вы печатаете массив целиком, потоки могут печатать значения в произвольном порядке. выводите на печать номер треда, который печатает это значение

    3) не сразу заметил. переменные, описанные вне pragma omp - общие для всех потоков. в итоге переменная с номером потока оказывается перезаписанной другим потоком. и к моменту сравнения в переменной уже будет значение чужого потока.

    int main()
    {
      int thread;
      int table[8] = { 0 };
      omp_set_num_threads(8);
    #pragma omp parallel private(thread)//всё, что дальше в скобках - будет запущено в 8 потоках одновременно
      { //потоки могут получать управление в произвольном порядке
        thread = omp_get_thread_num(); //каждый поток получает свой номер
        if (thread%2 ==0)  //четные потоки записывают в табличку единицу
            table[thread] = 1;
    #pragma omp critical //критическая секция в один момент времени может выполняться только одним потоком
        {               //это необходимо, чтобы печать из разных потоков не перемешивалась
            std::cout << "Hello, I am thread no " << thread << std::endl;
            std::cout << "My table value is" << table[thread] << std::endl;
        }               //потоки проходят секцию также в произвольной очередности
      }
    }
    Ответ написан
    3 комментария
  • Есть ли в языке C++ runtime?

    15432
    @15432
    Системный программист ^_^
    Есть там рантайм, в язык входят как минимум new и delete, которые без рантайма работать не будут.
    Ответ написан
    2 комментария
  • Как скомпилировать WIN-32 приложения для запуска на машинах без С/С++ компилятора?

    15432
    @15432
    Системный программист ^_^
    Свойства проекта / C++ / Code Generation / Runtime Library - сменить Multi-threaded DLL на Multi-threaded
    Ответ написан
    Комментировать
  • Что такое обобщение в c++?

    15432
    @15432
    Системный программист ^_^
    Кажется, тут термин "обобщенный" не относится к языку. Просто по примеру сделать такой же список, но для любых данных.
    Например, вот такой элемент списка:
    struct List
    {
        struct List * next;
        struct List * prev;
        void * data;
        int dataType;
    };

    способен хранить данные любого типа (в зависимости от dataType, указатель data будет интерпретироваться по-разному)
    Ответ написан
    Комментировать
  • Почему веб-клиент не подключается к Https?

    15432
    @15432
    Системный программист ^_^
    Это не ошибка, просто сайт перенаправляет вас на HTTPS версию. Некоторые сайты не позволяют работать по HTTP, насильно включая HTTPS таким образом
    Ответ написан
    8 комментариев
  • Почему теряем данные типа string в с++?

    15432
    @15432
    Системный программист ^_^
    string WorkPlace = (string)"";
    заменить на
    string WorkPlace = string("");
    или вообще на
    string WorkPlace;
    Ответ написан
  • Почему после преобразования ветки в бинарное дерево оно сразу же пропадает?

    15432
    @15432
    Системный программист ^_^
    Здесь вы создаёте новый Elem в локальной переменной 'to'
    to = new Elem;

    После выхода из функции этот указатель теряется, а исходный root не изменяется.

    Попробуйте передавать указатель по ссылке, например, так

    void Tree::Copy(const Elem* from, Elem* &to)
    Ответ написан
    1 комментарий
  • Проверить массив или первый элемент массива на пустоту?

    15432
    @15432
    Системный программист ^_^
    Во-первых, нужно сначала задать массиву начальные значения. Например, забить нулями вот так:
    int arr[10] = {0};

    Во-вторых, лучше завести отдельную переменную-флаг, в которой отмечать факт изменения массива пользователем.
    Ответ написан
    6 комментариев