2014-01-27 4 views
0

Я пытаюсь создать базовый класс стиля any в C++, называемый object. Он успешно компилируется, но прежде чем что-нибудь случится, я получаю ошибку: Unhandled exception at 0x008128C1 in object.exe: 0xC0000005: Access violation reading location 0xCCCCCCCC.:C++ Чтение местоположения нарушения доступа

#include <typeinfo> 
struct object 
{ 
public: 
    template < typename T > struct Data 
    { 
    public: 
     Data(T value) : val_(&value){} 
     Data() : val_(nullptr){} 
     T* value() 
     { 
      return val_; 
     } 
     ~Data() 
     { 
      delete &val_; 
     } 
     template < typename Tn > void Swap(Data<Tn>* D) 
     { 
      if (std::is_destructible<T>()) 
      { 
       val_->~T(); 
      } 
      Tn n_val = (Tn)val_; 
      std::swap<Tn>(&n_val, D->value()); 
     } 
    private: 
     T* val_; 
    }; 
    struct Inner : Data<void*> 
    { 
     template < typename T > void Cast() 
     { 
      Swap<T>(new Data<T>((T)NULL)); 
     } 
     template < typename T > void Cast(const T& value) 
     { 
      Swap<T>(new Data<T>(value)); 
     } 
    }; 
private: 
    Inner* Held; 
public: 
    template < typename T > object(const T& value) 
    { 
     Held->Cast<T>(value); 
    } 
    template < typename T > void operator=(const T& value) 
    { 
     Held->Cast<T>(value); 
    } 
    template < typename T > void cast() 
    { 
     Held->Cast<T>(); 
    } 
    template < typename T > void cast(const T& value) 
    { 
     Held->Cast<T>(value); 
    } 
    ~object(){ delete Held; } 
    const void* operator()() const 
    { 
     return *Held->value(); 
    } 
}; 

, а затем в моем тестовом файле

#include <iostream> 

int main() 
{ 
    object MyObject = 5; 
    std::cout << MyObject(); 
} 
+1

'delete &val_;' ??? – Roddy

+0

@DavidHeffernan: 'станд :: соиЬ << MyObject();': + \t \t 'MyObject \t {Held = 0x0053a140 {...}} \t object' (VC++ Autos) – Joe

+0

@Joe я отвалил ваш вопрос. У вас был отличный ответ. Совершенно несправедливо задавать другой вопрос о следующей проблеме, которую вы имеете. Обязательно задайте новый вопрос о своей другой проблеме. Или включите обе проблемы в один вопрос. Но не удаляйте исходный вопрос. Вы делаете ответ Джозефа глупым. –

ответ

4

Обратите внимание, что вы делаете delete Held;, даже если вы никогда не использовали new. Вы никогда ничего не назначаете Held, поэтому он не инициализируется при попытке сделать Held->Cast<T>(value);. Вам нужно будет выделить объект Held, прежде чем вы сможете это сделать.

У вас также возникла проблема с вашей структурой Data. Его конструктор берет копию своего аргумента, а затем вы храните указатель на эту копию. Эта копия является локальной для конструктора, хотя и будет уничтожена при завершении конструктора. Указатель val_ слева указывает на уничтоженный объект. Не только это, но затем вы делаете delete &val_;, который пытается освободить объект, у которого была автоматическая продолжительность хранения.

Вы действительно не должны использовать new и delete столько, сколько вы есть, и вы бы избежали многих проблем, которые у вас возникли.

0

Класс объекта ожидает данные, которые были выделены в куче. Это можно увидеть, так как вы получаете доступ к этим данным через указатель в своем классе объектов, свопите его значение и удаляя этот указатель.

В вашей основной функции вы строите объект с литеральным значением 5. Это значение не было выделено в куче, потому что не было вызвано выделение (никакой вызов нового не существует). 5 может быть выделено в стеке, но в качестве литерала он также может быть сохранен в программном ROM компилятором или в любом другом месте, где опасно получить доступ к адресу памяти.

В момент, когда ваш код пытается изменить данные по адресу буквального значения 5, вы совершили нарушение прав доступа, поскольку вы получаете доступ к памяти, которую ваша программа не разрешает напрямую изменять.

Чтобы решить эту проблему, вы, вероятно, захотите, чтобы ваш класс объекта выделил копию данных, передаваемых ему в кучу, чтобы затем он мог владеть и изменять и удалять по своему усмотрению.

Смежные вопросы