简体   繁体   中英

C++ Access violation reading location

I am trying to make a basic any style class in C++, called object . It compiles successfully, but before anything happens, I get the error: Unhandled exception at 0x008128C1 in object.exe: 0xC0000005: Access violation reading location 0xCCCCCCCC. :

#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();
    }
};

And then in my test file

#include <iostream>

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

Notice that you are doing delete Held; even though you never used new . You never actually assign anything to Held , so it is uninitialized when you attempt to do Held->Cast<T>(value); . You're going to have to allocate a Held object in some way before you can do that.

You also have a problem your Data struct. Its constructor takes a copy of its argument, and then you store a pointer to that copy. That copy is local to the constructor though and will be destroyed when the constructor ends. The val_ pointer is left pointing at the destroyed object. Not only that, but you then do delete &val_; which attempts to deallocate the object that had automatic storage duration.

You really shouldn't be using new and delete as much as you are, and you would avoid many of the problems you're having.

Your object class is expecting data that has been allocated on the heap. This can be seen since you are accessing that data via a pointer in your object class, swapping its value, and deleting that pointer.

In your main function you are building an object with a literal value of 5. This value has not been allocated on the heap because no allocation was called for (no call to new exists). 5 may have been allocated on the stack, but as a literal it might also be stored in program ROM by the compiler, or any other location where it is dangerous to access the memory address.

The moment your code attempts to modify the data at the address of the literal value 5, you have committed an access violation because you are accessing memory that you are not allowed by your program to modify directly.

To solve this you probably want your object class to allocate a copy of the data being passed to it on the heap that it can then take ownership of and modify and delete at will.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM