Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Оптимизировать функцию


Автор: zone51 2.3.2009, 23:46
Доброго времени суток товарищи! Пожалуйса помогите оптимизировать функцию, выполняющую последовательность простых действий.

Код

void __fastcall ProcessAction(){
 //Выводим сообщение в лог
 info("Procedure ProcessAction started");
 //Определяем номер дня недели - нужно для построения скл к базе данных
 int dof=DayOfWeek(Date());
 //Пишем сообщение в лог
 info("Day of week: "+IntToStr(dof));
 //Определяем колонки в базе для построения скл
 AnsiString startDate="FIELD_"+DefineDaysWeekFields(dof);
 AnsiString endDate="FIELD_SECOND_"+DefineDaysWeekFields(dof);
 //Выводим сообщение в лог
 info("Startdate "+startDate);
 info("Enddate "+endDate);
 //Текущие дата и время
 AnsiString currentTime="";
 AnsiString currentDate="";
 //Находим текущие дату и время
 DateTimeToString(currentTime,"hh:mm:ss",Time());
 DateTimeToString(currentDate,"yyyy-MM-dd",Date());
 //Выводим сообщение в лог
 info("CurrentTime "+currentTime);
 info("CurrentDate "+currentDate);
 //Составляем скл
 AnsiString sql="......";
 info("SQL: "+sql);
 //Запускаем инициализатор
 CoInitialize(NULL);
 //Создаем квери
 TADOQuery   *aq   =   new   TADOQuery(NULL);
 //Поток для БЛОБА
 TStream *bs=NULL;
 //Поток для фйала
 TFileStream *fs=NULL;
 //Файл для просмотра
 FILE *prevfile;
 //Строка подключение
 AnsiString connectionstring=".....";
 info("ConnectionString: "+connectionstring);
 //Запускаем
 aq->ConnectionString   =   connectionstring;
 aq->CommandTimeout=1;

 try{
    //Выполняем
    aq->SQL->Clear();
    aq->SQL->Add(sql);
    AnsiString path=FindINIValue("mediafolder");
    aq->Open();
    aq->ExecSQL();
    AnsiString fileName="";

    if(!aq->Eof){
      aq->First();
      //Получаем блоб
      bs = aq->CreateBlobStream(aq->FieldByName("gm_file_data"), bmRead);
      fileName=aq->FieldByName("gm_file_name")->AsString;
      info("Filename: "+fileName);
    }

    if(fileName==""){
      info("Filename is empty, showing background "+FindINIValue("Background"));
      ShowBkgOnMon(FindINIValue("background"));
      delete   aq;
      delete prevfile;
      if(bs!=NULL)bs->Free();
      if(fs!=NULL)fs->Free();
      return;
    }

    info("Path for prevfile: "+path+"\\"+CURRENT_FILE);
    prevfile=fopen((path+"\\"+CURRENT_FILE).c_str(),"r");

    //Сравниваем файды предыдущий и текущий
    if(prevfile!=NULL){
       info("Prevfile is not null");
       fseek(prevfile, 0L, SEEK_END);
       int size=ftell(prevfile);
       info("Size: "+IntToStr(size));
      if((size==bs->Size) && (CURRENT_FILE==fileName)){
        info("Files are the same ftell: "+IntToStr(size)+" file size:"+IntToStr(bs->Size)+" Current file: "+CURRENT_FILE+" fileName: "+fileName);
      }else{
       info("Files are not the same");
       fclose(prevfile);
       info("Path for creating a file:"+(path+"\\"+fileName));
       fs = new TFileStream(path+"\\"+fileName, fmCreate);
       CURRENT_FILE=fileName;
       //Copying
       fs->CopyFrom(bs, bs->Size);
       bs->Free();
       fs->Free();
       info("CURRENT="+CURRENT_FILE);
       ShowWindowOnMon(CURRENT_FILE);
      }
    }
    else{
      info("Prevfile is null");
      info("Path for file creating: "+(path+"\\"+fileName));
      fs = new TFileStream(path+"\\"+fileName, fmCreate);
      CURRENT_FILE=fileName;
      fs->CopyFrom(bs, bs->Size);
      bs->Free();
      fs->Free();
      info("Showing background");
      ShowWindowOnMon(CURRENT_FILE);
    }
    delete   aq;
    delete prevfile;
    CoUninitialize;
 }
 catch(int a){
   CoUninitialize;
   error("Error occurred code: "+IntToStr(a));
   delete   aq;
   delete prevfile;
   if(bs!=NULL)bs->Free();
   if(fs!=NULL)fs->Free();
 }
}


Пожалуйста помогите оптимизировать этот код в плане безопасности и утечек. Я пытаюсь определить как не допустить утечек памяти, отлов ошибок, работа с БД. Алгоритм такой:

Каждую минуту запускается данная функция. Она проверяет, поменялась ли информация в зависимости от времени, в базе данных, то есть в базе данных хранится информация о презентациях повер пойнт, в каждый момент времени может быть своя презентация - расписано по часам. Эта функция вызывается каждую минуту - требование проекта и нужно сделать ее очень надежной. Она просто смотрит если инфа в базе поменялась то копирует файл с базы в виде блоба на диск и проигрывает его если нет то ничего не делает.
Вопрсо в том как сделать это безопасно относительно утечек и т д. Помогите пожалуйста, у кого какие предложения, буду очень признателен, заранее огромное спасибо.

 smile  smile 

Автор: Alca 3.3.2009, 00:17
юзай std::auto_ptr
Код

std::auto_ptr<TADOQuery> apADOQuery(new TADOQuery(NULL));

Автор: Anikmar 3.3.2009, 01:24
На вскидку:
Цитата(zone51 @  2.3.2009,  23:46 Найти цитируемый пост)
   if(bs!=NULL)bs->Free();
   if(fs!=NULL)fs->Free();


Подход хороший, только там где эти объекты очищаются им после очистки не присваивается NULL. Может быть и нормально (нет под рукой хелпа), а может быть и двойная очистка. Если очистка сопряжена с самоуничтожением объекта - подозреваю, что так - так как delete я нигде не увидел, то возможны неприятности - сначала удалили, потом схватили исключение (банально лог не записался), в блоке catch еще раз удалили (причем вызовом метода уже уничтоженного объекта) AV 100%. 

Чисто из любопытства:
Такой подробный лог - чисто из отладочных целей или постоянно лупить столько записей будет?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)