crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

> Ошибка при работе с boost::any
AD
  опции профиля:
сообщение 9.8.2009, 21:12
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Почему-то вылетает с ошибкой при работе со следующим кодом:
void fillVectorTypes(std::vector<any>& types)
{
    DCW_HEAD type_1;            HEAD type_2;
    types.push_back(type_1);    types.push_back(type_2);
}

/// Инициализация заголовка карты и ее флагов
void CategoriesCharts::initMapEntity(const TabType key, MapEntity& entity)
{
    QFile file(entity.name());
    if(!file.open(QIODevice::ReadOnly)) return;
    qint64 sz = -1;
    std::vector<any> _types;
    fillVectorTypes(_types);
    file.read((char*)&_types[key], sizeof(_types[key]));
    file.close();
}


Правда, структуры не имеют конструкторов, но это код библиотеки:
struct DCW_HEAD
{
  char  title [16],
        File_name [8];
  float Latb, Late,
        Lonb, Lone,
        C0;
};

typedef unsigned char UByte;
typedef signed   char SByte;

struct HEAD
{
  char  title [TRS_TITLE_LEN],
        Corr_date [11],
        Chart_name [9],
        File_name  [9];
  float dlat, dlon,
        Latb, Late,
        Lonb, Lone,
        Latm, C0;
  short year_PD, month_PD,
        year_PP, month_PP,
        year_EC, month_EC;
  char  WGS;
  SByte  DP_mean,
        LH_dir,
        Datum,
        Proj,
        Type,
        Cntr,
        LangP,
        LangE,
        Reg,
        CntG,
        compress;

  SByte  WaterLevel,
        HO_mean,
        TypeEx;

  SByte  PubNum;
  SByte  CorrIssue;

  SByte  reserved [ 2 ];
  SByte  revision;
};


Отладчик выпадает на следующие строки:
~any()
        {
            delete content;
        }

Как можно исправить ошибку?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
BRE
  опции профиля:
сообщение 10.8.2009, 7:59
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


sizeof( any ) == 4, т.е. он хранит указатель на внутренний объект (content)!
Читая file.read((char*)&_types[key], sizeof(_types[key])) ты этот указатель затираешь первыми четырьмя байтами из файла. При разрушении any программа падает. Все логично. ;)
Обрати внимание на any_cast<Type>(...)!!!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 10.8.2009, 8:12
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата
sizeof( any ) == 4, т.е. он хранит указатель на внутренний объект (content)!
Читая file.read((char*)&_types[key], sizeof(_types[key])) ты этот указатель затираешь первыми четырьмя байтами из файла. При разрушении any программа падает. Все логично. ;)
Обрати внимание на any_cast<Type>(...)!!!

А как именно поправить я не понял? Прости, если донимаю...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 10.8.2009, 8:20
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(AD @ 10.8.2009, 9:12) *
А как именно поправить я не понял? Прости, если донимаю...

Примерно так:
void CategoriesCharts::initMapEntity(const TabType key, MapEntity& entity)
{
    QFile file(entity.name());
    if(!file.open(QIODevice::ReadOnly)) return;
    qint64 sz = -1;
    std::vector<any> _types;
    fillVectorTypes(_types);
    if( _types[ key ].type() == typeid( DCW_HEAD ) )
        file.read( (char*)&any_cast<DCW_HEAD>( _types[ key ] ), sizeof( any_cast<DCW_HEAD>( _types[key] ) ) );
    else if( _types[ key ].type() == typeid( HEAD ) )
        file.read( (char*)&any_cast<HEAD>( _types[ key ] ), sizeof( any_cast<HEAD>( _types[key] ) ) );
    file.close();
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 11.8.2009, 8:26
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(BRE @ 10.8.2009, 9:20) *
Примерно так:

Спасибо. А вопрос такой, а можно ли это сделать так, чтобы при добавлении, например, еще какого-то типа данных, ну например топографии другого формата, не надо было бы еще одну ветку else делать? Т.е. смысл-то этого вектора с any, чтобы он автоматом определял тип, а не при непосредственном приведении.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 11.8.2009, 12:17
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(AD @ 11.8.2009, 9:26) *
Цитата(BRE @ 10.8.2009, 9:20) *
Примерно так:

Спасибо. А вопрос такой, а можно ли это сделать так, чтобы при добавлении, например, еще какого-то типа данных, ну например топографии другого формата, не надо было бы еще одну ветку else делать? Т.е. смысл-то этого вектора с any, чтобы он автоматом определял тип, а не при непосредственном приведении.

Поэтому я тебе и написал, что не могу понять для чего ты все это делаешь. Теперь понял. ;)

IMHO any не очень подходит для таких задач. Можно попробовать получать имя типа из type_info, но все равно придется городить свой if для каждого типа. При добовлении нового типа, нужно будет дописывать свою ветвь.

Может лучше воспользоваться фабриками. Для каждого типа карты делается специальный класс loader, который умеет ее загружать. Все они регистрируются в фабрике и она создает объект-загрузчик в зависимости от указанного типа.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 11.8.2009, 12:22
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(BRE @ 11.8.2009, 13:17) *
Поэтому я тебе и написал, что не могу понять для чего ты все это делаешь. Теперь понял. ;)

IMHO any не очень подходит для таких задач. Можно попробовать получать имя типа из type_info, но все равно придется городить свой if для каждого типа. При добовлении нового типа, нужно будет дописывать свою ветвь.

Может лучше воспользоваться фабриками. Для каждого типа карты делается специальный класс loader, который умеет ее загружать. Все они регистрируются в фабрике и она создает объект-загрузчик в зависимости от указанного типа.

Об этом подумал. Какой класс буста использовать? :) Как приблизительно это можно реализовать? Спасибо за помощь!!!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме


Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 12.5.2024, 12:13