[英]What is the reason for a segmentation fault with this C++ code using lists?
我有一些復雜的C ++代碼,但問題push_back
於對結構列表進行push_back
:
list<cache_page> cachedPages;
void f()
{
cache_page cpage(a,b);
cachedPages.push_back(cpage);
}
我已經注釋了struct cache_page
所有數據成員,但錯誤仍然存在。 如果我評論push_back
行,則沒有錯誤。
可能是什么原因?
我嘗試使用GDB,並且_List_Node_base::hook()
函數中發生錯誤。
template < class T >
class A
{
T x;
public:
void func()
{
x->f();
}
};
class B : public A < B* >
{
list<cache_page> cachedPages;
public:
void f()
{
cache_page cpage;
cachedPages.push_back(cpage);
}
};
我有什么都不做的復制構造函數。 我在cache_page中沒有數據成員。
您越過溪流。 你沒看過《捉鬼敢死隊》嗎? 不要越過溪流。
您正在這里橫穿溪流:
class B : public A < B *>
我不明白這一點。 你想做什么? CRTP? 這不是完成的方式。
問題不在於回推,而是“ this”無效。
當你有
void f()
{
cache_page cpage;
}
它已編譯為NOP。 這不是可以接受的,一切都很好。
void f()
{
cache_page cpage;
// oops this access
this->cachedPages.push_back(cpage);
}
除了在A上下文中被調用外,它的值是什么? 它沒有在任何地方初始化。 因此,這等於內存中等待快樂的未初始化列表的任何內容。
解決辦法?
template < class T >
class A
{
T * _x;
public:
explicit A(T * x) : _x(x) {}
void func()
{
_x->f();
}
};
class B : public A < B >
{
list<cache_page> cachedPages;
public:
B(void) : A<B>(this) {}
void f()
{
cache_page cpage;
cachedPages.push_back(cpage);
}
};
這應該更好。 但是關於...
template < class T >
class A
{
public:
void func()
{
static_cast<T>(this)->f();
}
};
class B : public A<B>
{
list<cache_page> cachedPages;
public:
void f()
{
cache_page cpage;
cachedPages.push_back(cpage);
}
};
這就是CRTP的完成方式。
如果我沒記錯的話,某些(如果不是全部)STL容器需要復制構造函數和賦值運算符。 如果您依賴於這兩者的默認值,或者在應該進行深層復制時正在進行淺層復制,則可能是造成段錯誤的原因。
我想列出cpage對象的副本,如果cpage在這種情況下沒有segfault,您是否檢查過副本構造函數?
聽起來好像不存在cachedPages
。 可能已經刪除了嗎?
另外,f()是成員函數嗎? 您確定其( this
)對象仍然存在嗎? 我對成員函數內部的許多看起來很奇怪的問題感到困惑,只是在gdb中print *this
並意識到我已經在下一個堆棧框架中取消引用了錯誤的指針。
您可能正在重復刪除。 cpage的析構函數會做一些清理嗎? 如果真是這樣,並且cpage沒有復制構造函數(該構造函數會增加refcount或進行深層復制),則清理將發生兩次。
您需要指定賦值(=)運算符,以便排序例程可以將新順序分配給列表的成員。 之后,我認為您會沒事的。
發現了錯誤:這是一個非常微妙的錯誤。 在代碼中,x是一個指針,並且沒有在基類中初始化。 調用x-> f()會訪問vtable來調用派生類B中的正確函數。但是,由於指針值未初始化,因此“ this”參數是錯誤的。 然后,嘗試訪問該列表是無效操作,並且代碼崩潰。
要更正此錯誤,請在constrof類型T中傳遞com的參數,該參數將由派生類的構造函數初始化為。
class A
{
public:
A(T p): x(p)
{
}
};
class B
{
public:
B() : A(this)
{
}
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.