私は、固定サイズの配列とその配列へのインデックスとして実装されたカスタムFastStackクラスを持っています。new演算子が既存のオブジェクトを上書きする
私のコピーコンストラクタでは、私は配列を割り当て、コピーの配列から各オブジェクトを新しい配列に割り当てます。スタック上のオブジェクトにはいくつかのrefcountingがあるため、単純なコピーではなく代入が使用されます。
問題は、配列を割り当てるときに、他のスタックの配列の一部を上書きすることがあることです。予想されるように、これは、そのデータが逆参照されると最終的なセグメンテーションフォールトにつながる。
class FastStack {
private:
int m_size, m_ptr;
ObjectRef* m_stack;
public:
FastStack(int size) : m_size(size), m_ptr(-1) {
m_stack = new ObjectRef[m_size];
}
FastStack(const FastStack& copy) : m_size(copy.m_size), m_ptr(copy.m_ptr) {
long a = (long)copy.m_stack[0];
m_stack = new ObjectRef[m_size];
if ((long)copy.m_stack[0] != a)
fprintf(stderr, "\nWe have a serious problem!\n\n");
for (int i = 0; i <= m_ptr; i++)
m_stack[i] = copy.m_stack[i];
}
~FastStack() {
delete[] m_stack;
}
};
class ObjectRef {
private:
DataObj* m_obj;
public:
ObjectRef() : m_obj(0) { }
ObjectRef(DataObj* obj) : m_obj(obj) {
if (m_obj) m_obj->addRef();
}
ObjectRef(const ObjectRef& obj) : m_obj(obj.m_obj) {
if (m_obj) m_obj->addRef();
}
~ObjectRef() {
if (m_obj) m_obj->delRef();
}
ObjectRef& operator=(DataObj* obj) {
if (obj) obj->addRef();
if (m_obj) m_obj->delRef();
m_obj = obj;
return *this;
}
ObjectRef& operator=(const ObjectRef& obj) {
if (obj.m_obj) obj.m_obj->addRef();
if (m_obj) m_obj->delRef();
m_obj = obj.m_obj;
return *this;
}
};
「私たちには深刻な問題があります。 segfaultの直前にある行を調べて、gdbを実行すると、newによって作成されたObjectRefの1つが他のスタックの配列と同じアドレスを持つことがわかります。
私の最初の本能は、新しいものがすでに使用中のメモリを割り当ててはならないと言うことですが、明らかにここにあるようですが、何ができるのかについて完全な犠牲を払っています。
を追加しました:私はこれが起こる見る時、でm_size = 2とm_ptr = 0
このプログラムの完全なコードはhttps://github.com/dvpdiner2/pycdcでgithubの上にあるが、かなり複雑とフォローするのは困難です。
コンパイラのバージョンは?サードパーティのライブラリを使用していますか?あなたのビルドで 'sizeof(long)== sizeof(ObjectRef *)'が確実でしょうか?メモリを割り当てる他のプログラムの何千(何百万という)にも影響しないバグを「new operator」に発見したかもしれません。または、私たちに表示されていない他のコードにポインタや配列境界エラーがある可能性があります... – Blastfurnace
'FastStack :: operator ='が見つからず、 'FastStack: :〜Fastack'私たちが本当に必要とするのは、実行時に問題を示す**コンパイル可能な例**です。この**のようなすべてのコードスニペットと同様に、あなたは十分なコード**を見逃しています。 –