简体   繁体   English

C ++访问冲突读取位置

[英]C++ Access violation reading location

I am trying to make a basic any style class in C++, called object . 我试图在C ++中创建一个基本的any样式类,称为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. 它编译成功,但是在发生任何事情之前,我得到以下错误: 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; 注意,您正在执行delete Held; even though you never used new . 即使您从未使用过new You never actually assign anything to Held , so it is uninitialized when you attempt to do Held->Cast<T>(value); 您实际上从未分配任何东西给Held ,因此当您尝试执行Held->Cast<T>(value);时,它不会被初始化Held->Cast<T>(value); . You're going to have to allocate a Held object in some way before you can do that. 在执行此操作之前,您将必须以某种方式分配Held对象。

You also have a problem your Data struct. 您的Data结构也有问题。 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. val_指针指向被破坏的对象。 Not only that, but you then do delete &val_; 不仅如此,您还可以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. 您实际上不应该使用newdelete那样多,并且可以避免遇到许多问题。

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的对象。该值尚未在堆上分配,因为未调用任何分配(不存在对new的调用)。 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. 可能已经在堆栈上分配了5,但作为字面意义,它也可能由编译器或存在危险访问内存地址的任何其他位置存储在程序ROM中。

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. 当您的代码尝试修改字面值5的地址处的数据时,由于访问了程序不允许您直接修改的内存,因此发生了访问冲突。

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. 为了解决这个问题,您可能希望您的对象类在堆上分配传递给它的数据的副本,然后它可以拥有该所有权并随意修改和删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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