簡體   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