繁体   English   中英

C ++访问冲突读取位置

[英]C++ Access violation reading location

我试图在C ++中创建一个基本的any样式类,称为object 它编译成功,但是在发生任何事情之前,我得到以下错误: 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();
    }
};

然后在我的测试文件中

#include <iostream>

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

注意,您正在执行delete Held; 即使您从未使用过new 您实际上从未分配任何东西给Held ,因此当您尝试执行Held->Cast<T>(value);时,它不会被初始化Held->Cast<T>(value); 在执行此操作之前,您将必须以某种方式分配Held对象。

您的Data结构也有问题。 它的构造函数获取其参数的副本,然后存储指向该副本的指针。 但是,该副本是构造函数的本地副本,并且在构造函数结束时将被销毁。 val_指针指向被破坏的对象。 不仅如此,您还可以delete &val_; 尝试取消分配具有自动存储持续时间的对象。

您实际上不应该使用newdelete那样多,并且可以避免遇到许多问题。

您的对象类期望已在堆上分配的数据。 可以看到,因为您正在通过对象类中的指针访问该数据,交换其值并删除该指针。

在您的主要函数中,您正在构建一个文本值为5的对象。该值尚未在堆上分配,因为未调用任何分配(不存在对new的调用)。 可能已经在堆栈上分配了5,但作为字面意义,它也可能由编译器或存在危险访问内存地址的任何其他位置存储在程序ROM中。

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

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

暂无
暂无

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

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