2012-05-30 32 views
0

當我用寫緩衝區類自我得到一個訪問衝突錯誤:重載下標操作會導致訪問衝突

template<typename T> 
class Buffer { 
public: 
    Buffer(T *data, size_t len); 
    Buffer(size_t len); 

    size_t len(); 

    operator T*(); 
    T& operator[] (const int x) const { 
     return this->data[x]; 
    }; 

private: 
    T *data; 
    size_t _len; 
}; 

int main() { 
    Buffer<char> b("123", 3); 
    b[0] = 0; // This line causes "Access violation writing location 0x003c8830". 

    return 0; 
} 

這是爲什麼?我究竟做錯了什麼?

+2

刪除了'[c]'標籤,這顯然是C++。接下來,我們將不知道如何發生,直到我們看到構造函數,但我有一個模糊的想法... – Xeo

+1

字符串文字是隻讀的,猜測構造函數只是指向傳入的字符串。您可以發佈構造函數定義嗎? – hmjd

+0

你應該爲'data'分配內存 – triclosan

回答

1

導致問題的代碼是不是在後,但它很可能你的構造:如果你的指針data分配給成員data,那麼你將字符串存儲類內是恆定的。然後,main的代碼會嘗試寫入不可寫內存,從而導致訪問衝突。

您可以修復你的構造函數來避免這個問題:

Buffer(T *dataIn, size_t len) { 
    data = new T[len]; 
    memcpy(data, dataIn, len*sizeof(T)); 
} 
+1

嘿,不要偷我的神祕玻璃球的心靈調試! ;) – Xeo

1

"123"是一個字符串存儲在只讀存儲器,
當你這樣做:

b[0] = 0 

您正在嘗試寫到只讀存儲器,因此調用未定義的行爲

你需要動態分配內存data使其擁有內存和你的代碼,然後修改是所擁有的記憶,而不是不寫存儲器,它不擁有。
此外,請確保您按照Rule of Three

+0

祝賀傳奇徽章! –

+0

@LuchianGrigore:謝謝:) –

1

諸如「123」之類的字符串文字是不可寫的。當你做b [0] = 0時你嘗試給它賦值;

此外,字符串文字有一個終止NULL字符,使4長。

你可以專注於你的構造函數來複制const char輸入。

1

您沒有顯示構造函數的定義,但我敢打賭,您正在使用賦值運算符將C字符串複製到Buffer::data。您需要使用strcpy()。另外,您需要爲Buffer::data分配3 + 1個字節,以確保您有足夠的空間支持nul終結符。