S
Stasanych20 листопада 2016 р. 09:53

вопрос по ICMP

ICMP

вот тут https://evileg.com/post/167/
помогите пожалуйста пробую вашу программу а именно ту часть которая выполняет Ping я использую ее в цыкле так при повторном запуске потихоньку утекает память(ОЗУ) посмотрел вроде идет в конце free(ReplyBuffer); // Освобождаем память но не помогает очень нужно т.к. я не сильно разбираюсь(учусь только) программировать я в ВК добавился к вам можно и в нем ответить Черпаченко Станислав. Заранее очень благодарен на сайте у вас зарегался
Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

8
Evgenii Legotckoi
  • 21 листопада 2016 р. 09:33
Ну. Проверил я этот код в цикле и не заметил утечек памяти.
Функция free() используется для освобождения памяти, которая была выделена функцией malloc().
Те переменные, что есть в обработчике нажатия кнопки, сохраняются в стеке, поэтому они существуют локально в данном методе, ну или в теле цикла, если в цикл поместить.
Так что, у Вас имеется ошибка где-то помимо данного кода.
    S
    • 21 листопада 2016 р. 23:02
    прошу прощения, что не уточнил, возможно это важно! цикл запускается, в потоке, чтобы не вис интерфейс. Причем если запускать пустой поток, только с пустым циклом или заменить в этом цикле пинг(значение задержки) на случайное число, утечка не идет(память не растет постоянно, пока работает поток, немного увеличивается, потом срабатывает диструктор класса, запущенного в потоке и память опять возвращается на значение, до запуска потока), а если в цикле еще делать пинг адреса, то память растет постоянно в течении дня. делается программа мониторинга(доступности устройств в локальной сети и это критично).
      Evgenii Legotckoi
      • 22 листопада 2016 р. 00:08
      А не могли бы привести кусок кода, где инициализируется поток, и то место, где идёт работа с пингом. С проблемным участком.
        S
        • 22 листопада 2016 р. 00:33

        [spoiler=”Неполный код программы(много строк потому под споллер”]
        в заголовочном файле
        class MainWidget : public QWidget
        {
        Q_OBJECT

        public:
        explicit MainWidget(QWidget *parent=0);
        ~MainWidget();
        RaschetU *ras;

        };

        class PingGL : public QObject
        {
        Q_OBJECT

        public:
        explicit PingGL(QString adres, int mas2, int vrOg, QObject* parent=0);
        ~PingGL();

        public: int getValue() const { return pingTek;}
        private: int pingTek=1;

        signals:
        public slots:
        int slotPerDannye(QString adres, int mas2, int vrOg);
        };

        class RaschetU : public QObject
        {
        Q_OBJECT

        public:
        explicit RaschetU(QString adr[],QString zvu[],QString zve[],QString maxping[],QString inf0[],QObject* parent=0);

        QString *adrPotok, *zvuPotok, *zvePotok, *maxpingPotok, *inf0Potok;

        ~RaschetU();
        ________________________________

        MainWidget::MainWidget()
        {
        ………………..
        ………………..
        ………………..
        ras=0;
        sozdRAS();
        PotoK->start();

        reading();
        }

        void MainWidget::sozdRAS ()
        {
        if (ras)
        {
        qDebug () << “поток RAS существует – деллаю quit()”;
        while(ras)
        {
        PotoK->quit();
        QCoreApplication::processEvents();
        }
        }

        PotoK = new QThread;
        ras= new RaschetU(adr, zvu, zve, maxping, inf0); // передаю массивы в поток через конструктор
        ras->moveToThread(PotoK);

        connect (PotoK, SIGNAL(started()), ras, SLOT(run()));
        connect (ras, SIGNAL(finished()),PotoK, SLOT(quit()));
        connect (ras, SIGNAL(finished()),ras, SLOT(deleteLater()));
        connect (PotoK, SIGNAL(finished()),PotoK, SLOT(deleteLater()));
        connect (ras, SIGNAL(destroyed(QObject*)),this, SLOT(ObnulitUk15()),Qt::QueuedConnection);

        connect (ras, SIGNAL(signalpinAdr()), this, SLOT(slotpinAdr()),Qt::QueuedConnection);
        connect (ras, SIGNAL(signalDobZap(QString,QString,QString,QString)), this, SLOT(DobZap(QString,QString,QString,QString)),Qt::QueuedConnection);
        connect (ras, SIGNAL(signalPrevy(int,QString)), this, SLOT(slotPrevy(int,QString)),Qt::QueuedConnection);
        connect (ras, SIGNAL(signalPingTekMas(int,QString)), this, SLOT(slotPingTekMas(int,QString)),Qt::QueuedConnection);
        connect (ras, SIGNAL(signalZapChas(QDateTime,QDateTime)), this, SLOT(slotChas(QDateTime,QDateTime)),Qt::QueuedConnection);

        connect (ras, SIGNAL(signalObnProgr(int,QString)), this, SLOT(slotObnProgr(int,QString)),Qt::QueuedConnection);
        connect (ras, SIGNAL(signalZapTimera(int,int,QString, QString, QString, QString)), this, SLOT(slotZapTimera(int,int,QString, QString, QString, QString)),Qt::QueuedConnection);
        connect (ras, SIGNAL(runReadingL()), this, SLOT(readingL()),Qt::QueuedConnection);
        connect (ras, SIGNAL(runReading()), this, SLOT(reading()),Qt::QueuedConnection);
        connect (ras, SIGNAL(signalOBNNras(int)),grafiksWindow, SLOT(slotOBN(int)),Qt::QueuedConnection);

        }

        MainWidget::reading()
        {
        считывание массивов
        ……………..
        ReadinL();
        }

        MainWidget::reading()
        {
        рисование виджетов
        ……………..
        текст сейчас не важен т.к. рисование отключил чтобы ловить утечку в остальном коде
        }
        RaschetU::RaschetU(QString adr[],QString zvu[],QString zve[],QString maxping[],QString inf0[],QObject *parent) : QObject(parent)
        {
        adrPotok=adr;
        zvuPotok=zvu;
        zvePotok=zve;
        maxpingPotok=maxping;
        inf0Potok=inf0;
        }
        RaschetU::~RaschetU()
        {
        qDebug () << “Запущен диструктор RAS”;
        stop=false;
        return;
        }
        void RaschetU::run ()
        {
        qDebug () << “Запущен run (Начало ПОТОКА)”;
        if (comPing==1)
        {
        runzikl(pov);
        }

        }

        qDebug () << “отработал run (Конец ПОТОКА)”;
        qDebug () << “”;
        emit finished();
        }

        void RaschetU::runzikl (int pov)
        {
        QDateTime vrTek123,vr1123,vr2123,vr3123,vr4123,nowD123,nowD0123,vrNach123, now3123;

        QString nowDStr0123=””,nowDStr123=””,maxPingZv123=””, maxPing123=””;
        QString noPing123=””, noPingZv123=””,tabB123=””,nam123=””,adres123=””;
        int obnKn=0,razz=0,oRaz=0, Sec123=0,proz123=0;

        qDebug () << “начало Runzikl”;

        if ((stop==false)&&(otlRead==0))
        {
        tabB123=””;
        zapPi=1;
        nowD0123 = QDateTime::currentDateTime();
        nowD0123 = nowD0123.addSecs(-1);
        nowDStr0123 = nowD0123.toString(“yyyy-MM-dd hh:mm:ss”);
        }

        if ((desSek==false)&&(stop==false)&&(otlRead==0))
        {

        // qDebug () << ” время записи нулей в таблицу = ” << 0;

        if ((stop==false)&&(otlRead==0))for (int k123=0; k123<= razm-1; k123++)
        {
        if((stop==true)||(otlRead==1))
        {
        qDebug () << “останов по СТОП 2″;
        emit finished();
        break;
        }

        nam123=”Запись нулей”;
        proz123=(k123+1)*100/(razm);

        emit signalObnProgr(proz123,nam123);

        if (opov==0)
        {
        emit signalDobZap(adrPotok[k123],QString(“%1”).arg(“0″),”minutes”, nowDStr0123);

        emit signalDobZap(adrPotok[k123],QString(“%1”).arg(“0″),”hours”, nowDStr0123);
        }

        emit signalPrevy(k123,”0″);

        }
        desSek=true;
        vrNach123 = QDateTime::currentDateTime();
        vr1123 = QDateTime::currentDateTime().addMonths(-1); // минус месяц
        vr2123=vrNach123.addSecs(33); // плюс час от начала

        vr2Str=””;
        vrNachStr=””;

        }

        if ((stop==false)&&(otlRead==0))
        {
        if (vr2Str!=””)
        {
        vr2123 = QDateTime::fromString(vr2Str, “dd.MM.yyyy HH:mm:ss”);

        }
        if (vrNachStr!=””)
        {
        vrNach123= QDateTime::fromString(vrNachStr, “dd.MM.yyyy HH:mm:ss”);
        }

        vrTek123 = QDateTime::currentDateTime(); //текущее время
        vr3123 = vrTek123.addSecs(60); //плюс минута
        vr4123 = QDateTime::currentDateTime().addSecs(-28800); //минус 8 часов

        nowD123 = QDateTime::currentDateTime();
        nowDStr123 = nowD123.toString(“yyyy-MM-dd hh:mm:ss”);

        obnKn=0;

        if (vrTek123>=vr2123)
        {
        emit signalZapChas(vrNach123,vr2123);
        vr2123=vr2123.addSecs(33);
        vrNach123=vrNach123.addSecs(33);
        }

        now3123 = QDateTime::currentDateTime();

        noPing123= now3123.toString(“-hh:mm:ss- || dd//MM//yyyy”)+” || Адрес(а):\n”; noPingZv123=now3123.toString(“-hh:mm:ss- || dd//MM//yyyy”)+” || Адрес(а):\n”;
        maxPingZv123=now3123.toString(“-hh:mm:ss- || dd//MM//yyyy”)+” || Адрес(а) с повышенным PinG’ом:\n”; maxPing123=now3123.toString(“-hh:mm:ss- || dd//MM//yyyy”)+” || Адрес(а) с повышенным PinG’ом:\n”;
        }
        if ((stop==false)&&(otlRead==0))for (int i123=0; i123<= razm-1; i123++)

        {
        if((stop==true)||(otlRead==1))
        {
        qDebug () << “останов по СТОП 3″;
        emit finished();
        break;
        }

        if ((stop==false)&&(otlRead==0))
        {

        nam123=”PinG Базы ip адресов”;
        proz123=(i123+1)*100/(razm);

        emit signalObnProgr(proz123,nam123);

        adres123=adrPotok[i123];

        mas=3;

        classPingGL = new PingGL(adres123, mas2, 2000);

        pingTek=classPingGL->getValue();

        delete classPingGL;

        // qsrand(QTime(0,0,0).msecsTo(QTime::currentTime())); // временная замена пингу чтобы исключить утечку в самом пинге
        // Sleep(30);
        // pingTek=randomBetween(0,1000);
        // Sleep(1);

        // QCoreApplication::processEvents();

        if((stop==true)||(otlRead==1))
        {
        qDebug () << “останов по СТОП 4″;
        emit finished();
        break;
        }

        prev=0;

        if (pingTek==0)
        {
        prev=1;

        emit signalPrevy(i123,”1″);

        if (zvuPotok[i123]==”1″) noPingZv123+=inf0Potok[i123]+” “+adrPotok[i123]+”\n”;
        if ((zvePotok[i123]==”1″)&&(zvuPotok[i123]==”0″)) noPing123+=inf0Potok[i123]+” “+adrPotok[i123]+”\n”;

        }
        else if (pingTek>=maxpingPotok[i123].toInt())
        {
        prev=1;
        // prevyPotok[i123]=”2″;
        emit signalPrevy(i123,”2″);

        if (zvuPotok[i123]==”1″) maxPingZv123+=inf0Potok[i123]+” “+adrPotok[i123]+” время ответа>”+maxpingPotok[i123]+” mS\n”;
        if ((zvePotok[i123]==”1″)&&(zvuPotok[i123]==”0″)) maxPing123+=inf0Potok[i123]+” “+adrPotok[i123]+” время ответа>”+maxpingPotok[i123]+” mS\n”;
        }
        else
        {
        emit signalPrevy(i123,”0″);
        }

        emit signalPingTekMas(i123, QString(“%1”).arg(pingTek));

        emit signalDobZap(adrPotok[i123],QString(“%1″).arg(pingTek),”minutes”, nowDStr123);
        }
        }
        if ((stop==false)&&(otlRead==0))
        {
        nam123=”PinG Базы окончен”;
        proz123=0;
        emit signalObnProgr(proz123,nam123);

        nam123=””;

        if (noPingZv123.length()>40)
        {
        noPingZv123+=”не отвечают на PinG”;
        }

        if (noPing123.length()>40)
        {
        noPing123+=”не отвечают на PinG”;
        }

        if(opov==0)opov=1;

        obnKn=1;

        vrTek123 = QDateTime::currentDateTime();
        razz = vrTek123.toTime_t()-vrNach123.toTime_t();
        oRaz= 60-(razz-((razz/60)*60));

        if(vrTek123>vr3123)
        {
        Sec123= 60-vrTek123.toString(“ss”).toInt();
        qDebug () << “уже прошло больше минуты”;
        qDebug () << “Sec123=” << Sec123;
        qDebug () << “запускаю таймер на t = 0”;

        emit signalZapTimera(1,1, noPingZv123, noPing123, maxPingZv123, maxPing123);

        if((stop==true)||(otlRead==1))
        {
        qDebug () << “останов по СТОП 5”;
        emit finished();
        }

        }

        if(vrTek123<=vr3123)
        {
        razz=vr3123.toTime_t()-vrTek123.toTime_t();

        // emit signalZapTimera(razz,1, noPingZv123, noPing123, maxPingZv123, maxPing123);

        emit signalZapTimera(4,1, noPingZv123, noPing123, maxPingZv123, maxPing123);// временно для тестирования

        if((stop==true)||(otlRead==1))
        {
        qDebug () << “останов по СТОП 6”;
        emit finished();
        }

        }

        qDebug () << “конец Runzikl”;

        }

        return;
        }

        void MainWidget::slotZapTimera(int t,int nTimera,QString noPingZv123, QString noPing123, QString maxPingZv123, QString maxPing123)
        {
        while(ras)
        {
        // qDebug () << “Ждем окончания ПОТОКА”;
        QCoreApplication::processEvents();
        }
        if(!ras) qDebug () << “ПОТОК закрылся!!!!!!!!!!!!!!!!!!!”;

        if (nTimera==1)
        {

        // qDebug () << “таймер перезапущен на ” << t << ” секунд”;
        if(timer->isActive())timer->stop();
        timer->start(t*1000);
        }
        if (mas==3)
        {
        qDebug () << “”;
        qDebug () << “Запущен noPing”;
        // slotnoPing(noPingZv123,noPing123,maxPingZv123,maxPing123);
        }

        }

        void MainWidget::update ()
        {

        if(timer->isActive())timer->stop();

        if (pov1==1)
        {
        zapPi=1;
        if (postrGr1==1)
        {
        stopRisM=false;
        emit signalOBNN(1);

        }

        if (mas==3)
        {

        ui->pushButton_3->setText(“СтоП”);
        ui->pushButton->setEnabled(false);
        ui->checkBox->setEnabled(false);
        }
        if (mas==0)
        {
        ui->pushButton->setText(“СтоП”);
        ui->pushButton_3->setEnabled(false);
        }
        comPing=1;

        // qDebug () <<“ras перезапущен из update 1 pov1=” << pov1;
        sozdRAS();
        PotoK->start();

        }

        if (pov1==0)
        {
        if(ras)
        {
        PotoK->quit();
        PotoK->wait();
        while(ras)
        {
        QCoreApplication::processEvents();
        }
        }

        if (mas==3)
        {
        ui->pushButton_3->setText(“Ping массива”);
        ui->pushButton->setEnabled(true);

        }
        if (mas==0)
        {
        ui->pushButton->setText(“Ping адреса”);
        ui->pushButton_3->setEnabled(true);
        }
        comPing=0;
        ui->checkBox->setEnabled(true);
        }

        qDebug () <<“отработал update”;
        }

        void MainWidget::DobZap(QString ipadres, QString ping, QString tabliza, QString nowDStr123)
        {

        qDebug () << “начал работу СЛОТ Добавления”;

        sozSoed(“Dannye01″,”Dannye.sqlite”);

        QSqlDatabase *db=0;
        db = &QSqlDatabase::database(“Dannye01”);
        db->open();

        QSqlQuery query10= QSqlQuery(*db);

        query10.prepare(QString(“INSERT INTO ‘%1’ (datatime, ipadres, ping ) VALUES (:DateToday, :Ipadres, :Ping)”).arg(tabliza));

        query10.bindValue(“:DateToday”, nowDStr123);
        query10.bindValue(“:Ipadres”,ipadres);
        query10.bindValue(“:Ping”,ping);

        if (!query10.exec()){QCoreApplication::processEvents();
        qDebug() <<“ошибка добавления записи в талицу ” << tabliza;
        qDebug() << query10.lastError().text();

        }

        else qDebug() <<“Запись добавлена в таблицу: ” << tabliza;
        QCoreApplication::processEvents();

        db->commit();
        query10.finish();
        query10.clear();

        db->close();
        db=0;

        // zakSoed(“Dannye01”); // если раскомментировать то вылет краш

        qDebug () << “закончил работу СЛОТ Добавления”;

        }

        void MainWidget::sozSoed(QString name, QString fName)
        {
        QSqlDatabase *dbOSN=0;

        // qDebug () << QSqlDatabase::connectionNames ();
        if(QSqlDatabase::contains(name))
        {
        dbOSN = &QSqlDatabase::database(name);
        qDebug () << “в MainWidget соединение ” << name << ” уже создано”;
        // qDebug () << QSqlDatabase::connectionNames ();
        }
        else
        {
        // ———- Подключение к БД
        QString path;
        path = QCoreApplication::applicationDirPath();
        {
        dbOSN = &QSqlDatabase::addDatabase(“QSQLITE”,name);
        // dbOSN->setHostName(“127.0.0.1″);
        dbOSN->setDatabaseName(path+”/”+fName);
        // dbOSN->setDatabaseName(path+”/Dannye.sqlite”);
        // dbOSN->setUserName(“root”);
        // dbOSN->setPassword(“root”);

        if (!dbOSN->open())
        {
        qDebug () << dbOSN->lastError().text();
        oshbase=1;
        return;
        }
        else
        {
        // qDebug () << “”;
        // qDebug () << “в MainWidget подключение ” << name << ” Создано”;
        // qDebug () << QSqlDatabase::connectionNames ();
        oshbase=0;
        }
        }
        }
        dbOSN=0;
        }

        void MainWidget::zakSoed(QString name)
        {
        if(QSqlDatabase::contains(name))
        {
        QSqlDatabase *dbOSN=0;
        dbOSN = &QSqlDatabase::database(name);
        dbOSN->commit();
        dbOSN->close();
        QSqlDatabase::removeDatabase(name);
        dbOSN=0;
        qDebug() << “в MainWidget подключение ” << name << ” Удалено”;
        // qDebug () << “”;
        // qDebug() << “AfterDelete” << QSqlDatabase::database().connectionNames();
        }
        else qDebug() << “в MainWidget Подключение ” << name << ” не существует”;
        }

        [/spoiler]

          S
          • 22 листопада 2016 р. 00:38
          пытался засунуть под споллер не вышло. ping в этом коде засунул в отдельный класс думал так уйдет утечка до этого код Pinga был в классе который выполняется в потоке в void RaschetU::startping(adres)
            Evgenii Legotckoi
            • 22 листопада 2016 р. 09:40

            Какое безобразие… Зачем же названия методов и переменных транслитом?

            А если конкретно по делу, то вижу, что под переменную raz выделяется память.
            При этом в коде есть условия, которые проверяют, что переменная эта существует или нет. Значит допускается, что переменная может и не существовать, возможно, что даже она пересоздаётся при каких-то условиях. То есть под неё снова выделяется память. Вот только я так и не увидел оператора delete, который бы удалял её. Если этот объект где-то в программе пересоздаётся, но при этом не удаляется, то вероятно, что там может быть утечка памяти.

            Впрочем метод DobZap, тоже генерирует утечку памяти. В жизненном цикле программы достаточно один раз открыть подключение к базе данных. А потом просто работать с базой данных. У меня на сайте порядка 12 статей, где описывается работа с базой данных. Посмотрите те статьи, где идёт работа с таблицами. Там есть класс DataBase, можете от него отталкиваться. Воспользуйтесь поиском по сайту.

            А у Вас DobZap выделяет память, открывая базу данных, и не освобождает память при окончании работы с базой данных. Базу данных в таком случае надо закрывать, а память освобождать.
            Ладно бы, если в стеке всё сохранялось при работе в методе, тогда бы автоматически память была бы освобождена, а у Вас всё кидается в heap (кучу), а память не освобождается.

            Полагаю, что там ещё можно наковырять проблемных мест. Но тут всё нужно переписывать. Бросайте этот кипишь с лишь бы написать побыстрее и планомерно изучите по отдельности все вопросы, а именно:
            – работа с памятью, heap, стек, указатели, оператор new.
            – работа с базой данных.
            – работа с потоками.
            – и только потом уже PING ICMP WinAPI

            P/S/ Не приравнивайте указатель к нулю. В стандарте с++ уже давно для этого используется nullptr.
            То есть raz = 0; – это плохо.
            Правильно raz = nullptr;

              S
              • 26 листопада 2016 р. 07:15
              nullptr исправил везде и сделал многое из того, что вы написали исправить, и много еще ошибок нашел и исправил, но суть не в том…
              я запустил пустой поток, по кругу, прогонял программу в таком режиме, 3 часа. количество занимаемой памяти не увеличилось. добавил в поток ТОЛЬКО ping и пошла утечка. не сильная, но есть за 8 часов утекло 600 Килобайт не много но для программы которая выполняется постоянно это критично. Потому все же прошу, помочь Вас в выявлении утечки, в коде по по ICMP. Заранее благодарен за помощь.
              Люди на форумах подсказали что нужно в конце pinga нужно перед очисткой памяти попробовать это
              IcmpCloseHandle(hIcmpFile); но к сожалению это тоже не помогло
                Evgenii Legotckoi
                • 27 листопада 2016 р. 02:32

                Попробуйте вот такой вариант интегрировать в свою программу.

                HANDLE icmpHandle = IcmpCreateFile();
                int size_buffer = 32;
                char *sendBuffer = new char[size_buffer];
                IPAddr netaddr = inet_addr("192.168.0.1");
                unsigned long replySize = sizeof(ICMP_ECHO_REPLY) + size_buffer;
                LPVOID replyBuffer = (void*) malloc(replySize);
                 
                DWORD response = IcmpSendEcho(icmpHandle,netaddr , sendBuffer, size_buffer, NULL, replyBuffer, replySize, 1000);
                printf("Response from Send Echo is: %d\n", response);
                if (response>0)
                {
                    PICMP_ECHO_REPLY reply = (PICMP_ECHO_REPLY)replyBuffer;
                    printf("RTT: %d\n", reply->RoundTripTime);
                    IcmpCloseHandle(icmpHandle);
                    delete replyBuffer, sendBuffer;
                }
                else
                {
                    printf("Error %d\n", GetLastError());
                    IcmpCloseHandle(icmpHandle);
                    delete replyBuffer, sendBuffer;
                }

                 

                  Коментарі

                  Only authorized users can post comments.
                  Please, Log in or Sign up
                  AD

                  C++ - Тест 004. Указатели, Массивы и Циклы

                  • Результат:50бали,
                  • Рейтинг балів-4
                  m
                  • molni99
                  • 26 жовтня 2024 р. 01:37

                  C++ - Тест 004. Указатели, Массивы и Циклы

                  • Результат:80бали,
                  • Рейтинг балів4
                  m
                  • molni99
                  • 26 жовтня 2024 р. 01:29

                  C++ - Тест 004. Указатели, Массивы и Циклы

                  • Результат:20бали,
                  • Рейтинг балів-10
                  Останні коментарі
                  ИМ
                  Игорь Максимов22 листопада 2024 р. 11:51
                  Django - Підручник 017. Налаштуйте сторінку входу до Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                  Evgenii Legotckoi
                  Evgenii Legotckoi31 жовтня 2024 р. 14:37
                  Django - Урок 064. Як написати розширення для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
                  A
                  ALO1ZE19 жовтня 2024 р. 08:19
                  Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                  ИМ
                  Игорь Максимов05 жовтня 2024 р. 07:51
                  Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                  d
                  dblas505 липня 2024 р. 11:02
                  QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                  Тепер обговоріть на форумі
                  Evgenii Legotckoi
                  Evgenii Legotckoi24 червня 2024 р. 15:11
                  добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
                  t
                  tonypeachey115 листопада 2024 р. 06:04
                  google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
                  NSProject
                  NSProject04 червня 2022 р. 03:49
                  Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
                  9
                  9Anonim25 жовтня 2024 р. 09:10
                  Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

                  Слідкуйте за нами в соціальних мережах