Ответы пользователя по тегу C++
  • Как ограничить FPS в OpenGL и glut?

    @sddvxd
    Если нужно 60 FPS, то получить текущее время, секунду поделить на 60 и каждые 1/60 секунды обновлять кадр
    Ответ написан
    Комментировать
  • Как сделать такую ловушку?

    @sddvxd
    Я бы так сделал: сделал бы программу, которая внедряется в процесс, который создает процессы (например explorer.exe), в разделе импорта функции создания процессов поменял бы на свой и перехватывал создание процессов. При перехвате создания процесса вызывать оригинальный CreateProcess и запоминать дескриптор процесса. В только что созданный процесс внедрить dll для обработки опять же только что установленной ловушки на функцию открытия файла. Если filename == path_to_file/passwords.txt тогда самоуничтожение процесса

    PROC replaceProcAddress(LPCSTR callerModule, PROC original, PROC swap){
        HMODULE callerHandle = GetModuleHandleA(callerModule);
        if(callerHandle == nullptr)
            throw Exception(L"callerHandle is NULL in Process::replaceProcAddress");
    
        ULONG size;
        bool found = false;
        PIMAGE_IMPORT_DESCRIPTOR pImageDesc = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(ImageDirectoryEntryToData(callerHandle, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size));
        if(pImageDesc == nullptr)
            throw Exception(L"PIMAGE_IMPORT_DESCRIPTOR is NULL in Process::replaceProcAddress()");
    
        for(; pImageDesc->Name; pImageDesc++){
            PSTR pModName = reinterpret_cast<PSTR>(reinterpret_cast<PBYTE>(callerHandle) + pImageDesc->Name);
                PIMAGE_THUNK_DATA pThunkData = reinterpret_cast<PIMAGE_THUNK_DATA>(reinterpret_cast<PBYTE>(callerHandle) + pImageDesc->FirstThunk);
                for(; pThunkData->u1.Function; pThunkData++){
                    PROC* ppOriginalFunc = reinterpret_cast<PROC*>(&pThunkData->u1.Function);
                    if(*ppOriginalFunc == original){
                        found = true;
                        DWORD dwOldProtect;
                        if(VirtualProtect(ppOriginalFunc, sizeof(swap), PAGE_WRITECOPY, &dwOldProtect)){
                            if(!WriteProcessMemory(getHandle(), ppOriginalFunc, &swap, sizeof(swap), NULL))
                                throw Exception(L"Write memory is failed for replaceProcAddress");
                            VirtualProtect(ppOriginalFunc, sizeof(swap), dwOldProtect, &dwOldProtect);
                        }
                    }
                }
        }
        if(found) return swap;
        throw Exception(L"Address of procedure is not found in Process::replaceProcAddress()");
    }


    Это функция для смены адреса функции в разделе импорта на свой. Джеффри Рихтер
    Ответ написан
    Комментировать
  • Что такое *(float*)?

    @sddvxd
    Косвенное обращение к указателю, который приведен к типу float*

    В C++ принято использовать
    *reinterpet_cast<float*>()
    Ответ написан
    Комментировать
  • Удалить все повторяющиеся элементы из массива?

    @sddvxd
    Советую познакомиться с новыми стандартами языка и стандартной библиотекой
    bool inArray(int* arr, int need, int count){
        for(int i = 0; i < count; ++i)
            if(arr[i] == need)
                return true;
    return false;
    }
    int* uniq(int* arr, int size, int& newSize){
        int* localArr = new int[size]{0};
        for(int i = 0; i < size; ++i){
            if(inArray(localArr - newSize, arr[i], size))
                continue;
            ++newSize;
            *localArr++ = arr[i];
        }
    return localArr - newSize;
    }
    
    int main(){
        int arr[10] = {1,2,3,4,2,4,5,6,7,4};
        int newSize = 0;
        int* newArr = uniq(arr, sizeof(arr)/sizeof(int), newSize);
        for(int i = 0; i < newSize; ++i)
            cout << newArr[i] << "\n";
    }
    Ответ написан
    6 комментариев
  • Что означает void функции в скобках с++?

    @sddvxd
    Явное указание того, что функция не имеет аргументов
    Ответ написан
    Комментировать
  • Как преобразовать char массив в int С++?

    @sddvxd
    Благодаря обсуждению первого ответа и ответов автора можно организовать следующую программу:
    union conv{
        char (*pcarr)[4];
        int* pint;
    };
    
    static conv bconv;
    
    int main(){
        bconv.pint = new int(100);
        cout << *((int*)bconv.pcarr) << "\n"; //int to char (*)[4]
    
        bconv.pcarr = (char(*)[4])new char[4]{1,2,3,4};
        cout << *bconv.pint << "\n"; //char (*)[4] to int
    }


    union conv{
        unsigned char (*pcarr)[4];
        int* vint;
    };
    
    static conv bconv;
    
    
    int main(){
        bconv.vint = new int(100);
        cout << *((int*)bconv.pcarr) << "\n"; //int to char (*)[4]
    
        bconv.pcarr = (unsigned char(*)[4])new unsigned char[4]{255,255,255,127}; //big-endian
        if(INT_MAX == *bconv.vint) cout << "bingo\n";
    }
    Ответ написан
    Комментировать
  • В чём может быть проблема Run-Time Check Failure #3?

    @sddvxd
    Там написано "x2 был использован без инициализации"
    Ответ написан
  • Возможно ли в С++ создать динамический класс-мимик, который может более одного раза "мимикрировать" под другой класс?

    @sddvxd
    class MimicBase{};
        class Vampire : public MimicBase{
        public:
            Vampire();
            Vampire(MimicBase& m) : MimicBase(m){};
        };
        class Elf : public MimicBase{
        public:
            Elf();
            Elf(MimicBase& m) : MimicBase(m){};
        };
    
        MimicBase m1;
        Vampire v1(m1);
        MimicBase m2(v1); //Обратно


    Суть в том, что при инициализации объекта класса, например, Vampire, вы берете под контроль вызов цепочки конструкторов и можете подставить объект родителя
    Ответ написан
    5 комментариев
  • C++ как заполнить вектор рандом?

    @sddvxd
    #include <iostream>
    #include <cstdio>
    #include <math.h>
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        int* feel(const short&);
        int count = 20;
        int* pArrMain = feel(count);
        for(int i = 0; i < count; ++i){
            if(i % 10 == 0) cout << '\n';
            cout << pArrMain[i] << " ";
        }
    }
    
    int* feel(const short& count = 100){
        if(count <= 0) throw runtime_error("Bad size");
        int* pArr = new int[count];
        for(int i = 0; i < count; ++i)
            pArr[i] = rand() % 21;
        return pArr;
    }


    хм, у меня разные значения из рандом, может что-то поменяли и не нужно семя менять
    Ответ написан
    Комментировать
  • Как реализовать градиент серого цвета без использования графических библиотек (OpenCV и т.д.) на C/C++?

    @sddvxd
    Если вам действительно нужна идея, а не код готовой программы, вот вам моя мысль:

    int rows = 0, cols = 0;
        cout << "Enter size (Example: 200x200)\n";
        cin >> rows >> cols;
        if(rows <= 0 || cols <= 0) throw runtime_error("Bad size");
        int pixmap[rows][cols];
        for(int i = 0; i < rows; ++i){
            double position = double(i) / rows;   //Вычисляем "высоту"
            int color = position * 255;                 //и находим подходящий цвет
            cout << position << " " << color << '\n';
            for(int j = 0; j < cols; ++j)
                pixmap[i][j] = color;
        }


    FINAL VERSION:
    #include <iostream>
    #include <cstdio>
    using namespace std;
    
    void main()
    {
        int rows = 0, cols = 0;
        char* filename = "test.pgm";
        cout << "Enter size and filename (Example: 200x200 mygradient.pgm)\n";
        cin >> rows >> cols >> filename;
        if(rows <= 0 || cols <= 0) throw runtime_error("Bad size");
        FILE* pfile = fopen(filename, "w");
        fprintf(pfile, "P2\n%d %d\n255\n", cols, rows);
        for(int i = 0; i < rows; ++i){
            double position = double(i) / rows;
            int color = position * 255;
            cout << position << " " << color << "\n";
            for(int j = 0; j < cols; ++j)
                fprintf(pfile, "%d ", color);
            fprintf(pfile, "\n");
        }
    }


    Вводить например вот так: 1500x400 file.pgm
    5bfb1d672efdc256620573.png
    Ответ написан
  • С++, Как решить такое на с++???

    @sddvxd
    #include <iostream>
    
    int main(){
      std::cout << "Enter the number: ";
      int number;
      std::cin >> number;
      int buffer = number;
      if(number <= 0) return 1;
      double multi_factor = 1;
      std::cout << std::endl;
      while((buffer = number * multi_factor) >= 1){
        std::cout << buffer << " ";
        multi_factor /= 2;
        if(buffer % 2 != 0) break;
      }
    
      std::cin.get();
      std::cin.get();
    
      return 0;
    }
    Ответ написан
    Комментировать
  • Почему первые 4 байта QString заняты?

    @sddvxd Автор вопроса
    Все, понял. bufferOut << pLineEdit->text(); возвращает объект QString, уже инициализированный строкой из QLineEdit, а значит у него уже стоит длина 12. Из-за своего малого опыта я думал, что мне вернется строка, но вернулся весь объект QString
    Ответ написан
    Комментировать
  • Когда вызывается сигнал "QTcpSocket::readyRead()"?

    @sddvxd Автор вопроса
    Решил свой вопрос. Просто поставил задержку между записью 2 секунды и начал отладку серверного приложения - сигнал QTcpSocket::readyRead() вызывается только при полном принятии байтов
    Ответ написан
    Комментировать
  • Почему не вызвать конструктор с производным классом в аргументе?

    @sddvxd Автор вопроса
    Человек оставил ответ, но почему-то удалил

    Проблема была в explicit. Компилятору все равно, что я передаю объект базового класса

    SimpleItemSelectionModel::SimpleItemSelectionModel(QObject *parent) : QItemSelectionModel (dynamic_cast<QAbstractItemModel*>(parent))
    Ответ написан
  • Почему в виджете QTabWidget не показывает список строк в виджете QListView?

    @sddvxd Автор вопроса
    Затупил конкретно... При выходе из конструктора класса все члены, которые не являются членами класса удаляются... Объявил членами класса и присвоил указатели - все работает
    Ответ написан
    Комментировать
  • Как "обрезать" часть массива LPCWSTR?

    @sddvxd Автор вопроса
    Решил проблему:

    wchar_t *subwstr(const wchar_t *str, size_t startPos, size_t len)
    {
        wchar_t* temp = new wchar_t[wcslen(str)+100];
        wmemcpy(temp, str, 100);
        temp[startPos + len] = '\0';
        return temp + startPos;
    }
    const wchar_t* subw = subwstr((LPCWSTR)ObjectAttributes->ObjectName->Buffer, 4, wcslen((LPCWSTR)ObjectAttributes->ObjectName->Buffer));
    Ответ написан
  • Как правильно создать Copy Constructor для Class Queue and Double List?

    @sddvxd
    Явные конструкторы копирования объявляются лишь в тех случаях, когда функционала неявного недостаточно, то-есть, например, Queue динамически выделяет память:

    class Queue{ 
    public:
        char * name;
        Queue(const * char ch){
            name = new char[strlen(ch)+1];
            memcpy(name, ch, strlen(ch)+1); 
        };
        ~Queue(){
            delete [] name;
        };
    }


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

    Queue * q1 = new Queue("test");
    Queue q2(*q1);
    delete q1;
    std::cout<<q2.name; //Утечка памяти


    Давайте же сделаем правильно:
    Queue::Queue(const Queue & rq){
        delete [] name;
        name = new char[strlen(rq)+1];
        memcpy(name,rq,strlen(rq)+1);
    }
    Queue & Queue::operator=(const Queue & rq){
        if(this==&rq)return *this;
        delete [] name;
        name = new char[strlen(rq)+1];
        memcpy(name,rq,strlen(rq)+1);
        return *this;
    }


    Теперь получаем:

    Queue * q1 = new Queue("test");
    Queue q2(*q1);
    delete q1;
    std::cout<<q2.name; //test
    Ответ написан
    Комментировать
  • Зачем в производных классах делать виртуальную функцию?

    @sddvxd Автор вопроса
    Разобрался благодаря статье https://msdn.microsoft.com/ru-ru/library/0y01k918.aspx
    Ответ написан
    Комментировать
  • Почему компилятор не находит прототип?

    @sddvxd Автор вопроса
    Разобрался: необязательные параметры должны находиться справа
    Ответ написан
    Комментировать