0

自己記述のBufferクラスを使用すると、アクセス違反エラーが発生します。

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;
}

何故ですか?私は何が間違っているのですか?

4

4 に答える 4

1

"123"読み取り専用メモリに格納されている文字列リテラル
です。

b[0] = 0

読み取り専用メモリに書き込もうとしているため、未定義動作が呼び出されます。

動的メモリをに割り当てて、メモリを所有するdataようにする必要があります。次に、コードは、所有していない書き込み不可能なメモリではなく、所有しているメモリを変更します。また、三つのルールに 従っていることを確認してください。

于 2012-05-30T11:10:52.430 に答える
1

「123」などの文字列リテラルは書き込み不可です。b [0] = 0の場合、値を割り当てようとします。

さらに、文字列リテラルには終了NULL文字があり、その4文字が長くなります。

コンストラクターを特殊化して、constchar入力をコピーできます。

于 2012-05-30T11:10:55.410 に答える
1

問題の原因となるコードは投稿にありませんが、コンストラクターである可能性が非常に高くなります。dataメンバーdataにポインターを割り当てると、クラス内に文字列定数が格納されます。次に、thanのコードがmain書き込み不可能なメモリに書き込もうとし、アクセス違反を引き起こします。

この問題を回避するためにコンストラクターを修正できます。

Buffer(T *dataIn, size_t len) {
    data = new T[len];
    memcpy(data, dataIn, len*sizeof(T));
}
于 2012-05-30T11:09:14.357 に答える
1

コンストラクターの定義は表示されていませんが、代入演算子を使用してC文字列をにコピーしているに違いありませんBuffer::data。代わりにを使用する必要がありますstrcpy()Buffer::dataまた、 nulターミネータ用の十分なスペースを確保するために、に3+1バイトを割り当てる必要があります。

于 2012-05-30T11:11:32.180 に答える