Поиск:

Ответ в темуСоздание новой темы Создание опроса
> странный вылет программы 
:(
    Опции темы
Vyacheslav
Дата 11.1.2007, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Цитата(Sfairet @  11.1.2007,  17:20 Найти цитируемый пост)
к томуже не каждый компилятор согласиться генерировать исключение bad_alloc, а также просто будет использовать вариант с 0 

Это как это? И кто его , компилятор, спрашивать будет? smile 
А вариант, уверяю Вас, безнадежный. Особенно, при собеседовании при преме на работу smile



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Sfairet
Дата 11.1.2007, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 11.1.2007

Репутация: нет
Всего: нет



Имелись ввиду компиляторы не совместимые со стандартом=)

Да я и не спорю что вариант с нулём большая редкость, но тем не менее при определенных обстаятельствах он не исключён=)
PM MAIL   Вверх
Bima
Дата 12.1.2007, 07:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 15.8.2006

Репутация: 2
Всего: 2



Sfairet  и Vyacheslav  скажите, а будет ли работать такой код???
Код

try{
     char* pchar = new char[size];
     }
catch(...)  
      {
      //Error
      } 



--------------------
Чтобы дойти до цели, надо идти.

Клавиатура и мышь - это главные инструменты прогресса.
PM MAIL WWW   Вверх
stmamont
Дата 12.1.2007, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 343
Регистрация: 13.3.2004
Где: влг

Репутация: 3
Всего: 3



Bima, вот к этому и велось)
именно так и нужно отлавливать ошибку


--------------------
user posted image
PM MAIL ICQ   Вверх
Vyacheslav
Дата 12.1.2007, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Вот так 
Код

catch(...)  
      {
      //Error
      } 

все таки не стоит.  Лучше по-аккуратнее
Код

catch(std::bad_alloc ex)  
 {
      //Error
 } 


или хотя бы так
Код

catch(std::exception& ex)  
 {
      //Error
 } 





--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Bima
Дата 16.1.2007, 10:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 15.8.2006

Репутация: 2
Всего: 2



набрал у себя в программе при создании потока следущее:
Код

try
  {
  TMethread *thr1 = new TMethread(true);
  }
catch(std::exception ex)  
 {
      //Error
 } 


по сути дела, то же самое, но у меня ругается на строку:
catch(std::exception ex)

Что не так, где подвох???


--------------------
Чтобы дойти до цели, надо идти.

Клавиатура и мышь - это главные инструменты прогресса.
PM MAIL WWW   Вверх
pandrew
Дата 16.1.2007, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 213
Регистрация: 27.3.2006

Репутация: 3
Всего: 3



Добавь #include <except.h>
Кроме того thr1 не будет видно вне скобок. Едва ли ты это хотел.
PM MAIL   Вверх
Bima
Дата 16.1.2007, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 15.8.2006

Репутация: 2
Всего: 2



Цитата

Добавь #include <except.h>

Заработало. Vyacheslav  писал, что лучше использовать:
Код

catch(std::bad_alloc ex)  
 {
      //Error
 } 

Для создания потоков с помощью new это тоже применимо, или есть std, какой нибудь другой???

Цитата

Кроме того thr1 не будет видно вне скобок. Едва ли ты это хотел. 

что значит не будет видно???
Я его создал в скобках, он отработал и убился. Приостанавливать и завершать экстренно мне его не нужно.


--------------------
Чтобы дойти до цели, надо идти.

Клавиатура и мышь - это главные инструменты прогресса.
PM MAIL WWW   Вверх
stmamont
Дата 16.1.2007, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 343
Регистрация: 13.3.2004
Где: влг

Репутация: 3
Всего: 3



если обобщить
Код

#include <except.h>

...

TMethread *thr1;
try
  {
  thr1 = new TMethread(true);
  }
catch(std::exception ex)  
 {
      //Error
 } 



--------------------
user posted image
PM MAIL ICQ   Вверх
Vyacheslav
Дата 16.1.2007, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Код

#include <exception>

Это во-первых.
Во-вторых, если Вы используете VCL, его разработчики как правило перехватывают первоначальные исключения и вместо них генерят свои с типом Exception. Так что, Ваш код должен выглядеть примерно так
Код

try
  {
  TMethread *thr1 = new TMethread(true);
  }
catch(Exception* ex)  
 {
      //Error
 } 

В-третьих, абослютно не вижу смысла ловить исключения по месту. По месту стоит ловить их тогда, когда есть возможность что-то исправить. Здесь же ясно, что объект не создался(неважно по какой причине) и программу либо следует прекратить полностью, либо прекратить выполнение конкретного участка  с выдачей информации.  По этому я бы здесь исключение не ловил. А все сделал централизованно
Вообще любая программа должна начинаться с организации обработки ошибок.
Слава богу, разработчики VCL продумали это за нас. И я обычно делаю так.
1. Выкладываю ApplicationEvents, который использую для централизовааной обработки всех действий
2. Задаю обработчик исключений типа
Код

void __fastcall TMainDataModule::ApplicationEventsException(
      TObject *a_Sender, Exception *a_Exc)
{
// Если это клиентское исключение, то просто выдаем сообщение...
    try
    {
        if (EipException* Exc = dynamic_cast<EipException*>(a_Exc))
        {
            Exc->Show();
            return;
        }
        // Если это серьезная ошибка
        std::auto_ptr<TErrorDialog> Dlg(new TErrorDialog(this, a_Exc,a_Sender));
        Dlg->ShowModal();
        // если ошибка произошла при входе в систему,
        // прекращаем работу
        if (m_Logining)
            Application->Terminate();
    }
    catch(...)
    {
    }
}

здесь catch(...) к месту, потому что этот код не должен генерить исключение во вне.
В коде я подменяю по возможности первичные исключения на свои
Код

/////////////////////////////////////////////////////////////////////////////
// ## Назначение: Собственный класс исключения
// ## Описание :  В Message содержится код сообщения
class PACKAGE EipException: public Exception
{
private:
    bool m_NotCode;
    TVarRec* m_Args;
    int m_Size;
    TMsgDlgType  m_DlgType;
public:
#pragma option push -w-inl
    __fastcall EipException(AnsiString a_Msg):Exception(a_Msg){};
    __fastcall EipException(AnsiString a_Msg, TMsgDlgType a_DlgType)
                            :Exception(a_Msg),
                             m_NotCode(true),
                             m_DlgType( a_DlgType){};
#pragma option pop
    __fastcall EipException(AnsiString, const System::TVarRec*, const int);
    void __fastcall Show(void);
    __fastcall ~EipException(void);
};

Ну и вся обработка в самом коде сводится к
1.Сами генерим исключение
Код

TAdsConnection* __fastcall TPluginModule::GetMainConnection()
{
    if (!ComponentState.Contains(csDesigning))
    {
       static TAdsConnection* Connection = dynamic_cast<TAdsConnection*>(
            Screen->DataModules[0]->FindComponent(cMainConnection));
        if (!Connection)
            throw Exception(Format("AdsConnection '%s' не найден",
                                    ARRAYOFCONST((cMainConnection))));
        return Connection;
    }
    return NULL;
}

2.Подменяем первоначалые на свои
Код

bool __fastcall TMainDataModule::Login(TObject*         a_Sender,
                                       const AnsiString& a_User,
                                       const AnsiString& a_Password,
                                       const AnsiString& a_Database)
{
    try
    {

        MainConnection->ConnectPath  =
                           IncludeTrailingPathDelimiter(a_Database)
                         + cDictionaryName;
        MainConnection->Username = a_User;
        MainConnection->Password = a_Password;
        MainConnection->IsConnected = true;
    }
    catch(EADSDatabaseError* Exc)
    {
        switch (Exc->ACEErrorCode)
        {
          case AE_FILE_NOT_FOUND:
              throw EipException(NotFoundDictionary
                               + QuotedStr(a_Database),mtError);
          case 7078:
              throw EipException(NotUserAuthenticate,mtError);
          default:
              throw;
        }
    }
    return true;
}

 






--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Лена
Дата 16.1.2007, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



>смысл такой: оператор new выкидывает exception если система не смогла выделить память.

Значит в книге Архангельского ошибка? Там сказано, что просто вернется NULL, в случае не возможности выделить память через new.
PM MAIL   Вверх
Vyacheslav
Дата 16.1.2007, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Цитата(Лена @  16.1.2007,  12:22 Найти цитируемый пост)
Значит в книге Архангельского ошибка? Там сказано, что просто вернется NULL, в случае не возможности выделить память через new

Архангельского надо читатать с осторожностью smile



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
mrbrooks
Дата 16.1.2007, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 167
Всего: 306



Цитата(Vyacheslav @ 16.1.2007,  13:01)

Архангельского надо читатать с осторожностью smile

Это почему. Не ужели автор допускает такие ошибки? Это конечно не в тему. Заранее пардон.
PM MAIL   Вверх
Anikmar
Дата 16.1.2007, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 34
Всего: 59



И у Архангельского и в стандартном HELPе ошибки есть.
Нет в мире ничего совершенного.  smile 
PM MAIL ICQ   Вверх
Vyacheslav
Дата 16.1.2007, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Цитата(mrbrooks @  16.1.2007,  14:43 Найти цитируемый пост)
Это почему. Не ужели автор допускает такие ошибки? Это конечно не в тему. Заранее пардон. 

Потому что, для Архангельского - главное объем.  Правда такие ошибки - верх некомпетентности. В конце концов если не со стандартом, то хотя бы с хелпом следовало ознакомиться повнимательнее
Цитата( C++Builder Help)

Category

Operators, C++-Specific Keywords

Syntax

void *operator new(std::size_t size) throw(std::bad_alloc);

void *operator new(std::size_t size, const std::nothrow_t &) throw();
void *operator new[](std::size_t size) throw(std::bad_alloc);
void *operator new[](std::size_t size, const std::nothrow_t &) throw();
void *operator new(std::size_t size, void *ptr) throw();    // Placement form

void *operator new[](std::size_t size, void *ptr) throw();  // Placement form

Description

The new operators offer dynamic storage allocation, similar but superior to the standard library function malloc. These allocation functions attempt to allocate size bytes of storage. If successful, new returns a pointer to the allocated memory. If the allocation fails, the new operator will call the new_handler function. The default behavior of new_handler is to throw an exception of type bad_alloc. If you do not want an exception to be thrown, use the nothrow version of operator new.  The nothrow versions return a null pointer result on failure, instead of throwing an exception.
The default placement forms of operator new are reserved and cannot be redefined. You can, however, overload the placement form with a different signature (i.e. one having a different number, or different type of arguments). The default placement forms accept a pointer of type void, and perform no action other than to return that pointer, unchanged. This can be useful when you want to allocate an object at a known address. Using the placement form of new can be tricky, as you must remember to explicitly call the destructor for your object, and then free the pre-allocated memory buffer. Do not call the delete operator on an object allocated with the placement new operator.

A request for non-array allocation uses the appropriate operator new() function. Any request for array allocation will call the appropriate operator new[]() function. Remember to use the array form of operator delete[](), when deallocating an array created with operator new[]().

Note:    Arrays of classes require that a default constructor be defined in the class.

A request for allocation of 0 bytes returns a non-null pointer. Repeated requests for zero-size allocations return distinct, non-null pointers.

Только вот эта форма буде возвращать NULL
Код

void *operator new(std::size_t size, const std::nothrow_t &) throw();
void *operator new[](std::size_t size, const std::nothrow_t &) throw();

Обычные  генерят exception



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0609 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.