2014-02-07 35 views
4

(C++)我在堆上分配了內存對齊的實例,然後在另一個線程中刪除它們。該代碼是這樣的:從另一個線程中刪除對齊的內存

ALIGNED class Obj 
{ 
public: ALIGNED_NEW_DELETE 
... 
}; 

Thread 1: 
Obj *o = new Obj; // overloaded new for aligned memory allocation 
postTask(o); 

Thread 2: 
o->runTask(); 
delete o; // overloaded delete for aligned memory deletion 
// "delete" statement crashes 

螺紋2 DELETE語句將在Visual Studio 2013(_BLOCK_TYPE_IS_VALID)給出一個斷言錯誤。 奇怪的是,如果我刪除創建線程中的對象,一切運行良好。

爲什麼會出現這種情況?什麼是解決方案?

編輯:

@ galop1n:其實我現在使用的是本徵的內置新/ delete操作符EIGEN_MAKE_ALIGNED_OPERATOR_NEW。我也嘗試過我自己的運營商,都失敗了。

對於Eigen的運營商,請自行查找來源。

對於我的分配器:

void* operator new(size_t size){ return alignedMalloc(size, align); } 
void operator delete(void* ptr) { alignedFree(ptr); } 
void* operator new[](size_t size) { return alignedMalloc(size, align); } 
void operator delete[](void* ptr) { alignedFree(ptr); } 


void* alignedMalloc(size_t size, size_t align) 
{ 
    char* base = (char*)malloc(size + align + sizeof(int)); 
    if (base == nullptr) 
      ASSERT(0, "memory allocation failed"); 
    char* unaligned = base + sizeof(int); 
    char* aligned = unaligned + align - ((size_t)unaligned & (align - 1)); 
    ((int*)aligned)[-1] = (int)((size_t)aligned - (size_t)base); 
    return aligned; 
} 

void alignedFree(const void* ptr) { 
    int ofs = ((int*)ptr)[-1]; 
    free((char*)ptr - ofs); 
} 

,並將校準的宏__declspec(對齊(16))。它崩潰時有或沒有「ALIGNED」屬性。

+0

你實際上是否在調用'delete'之前等待'o'構造? –

+0

@mfukar:是的,一切都完美同步。實際上,如果我創建不對齊的實例,刪除語句運行良好。 – Defd

+0

@Defd然後它必須處理您的自定義分配器。 – galop1n

回答

1

這是尷尬,問題是在線程2,與obj *被鑄造成一個基類的指針任務*,以及用於絕對愚蠢:〜任務()不是虛擬:

class Task 
{ 
public: 
    ~Task(); // <-- not virtual, therefore it crashes 
    ... 
} 

ALIGNED class Obj : public Task 
{ ... } 

早應該早得多發現這個問題。因爲,正如在我對問題的描述中,我自己說的那樣,它給出了一個斷言錯誤:_BLOCK_TYPE_IS_VALID,這是一個Visual Studio調試庫,用於默認的刪除操作符,這意味着它甚至沒有運行到我的重載刪除操作符中,這最終意味着我錯過了一個「虛擬」。

這是我的錯,我甚至忘記了將類繼承添加到問題中。

有時,我可能被困在一個小時甚至幾天的問題。但在我在線發佈該問題後,我可以立即找到答案。不知道你們之中是否有過類似的問題;也許我已經給自己施加了太多的壓力。

不過,謝謝你,互聯網。

+1

總是這樣的:一旦我遇到了一個難以解決的難題,我試圖在一個全面的問題中提出這個問題,以便發佈在SO上 - 只是爲了認識到實際上有一個明顯而且通常簡單的解決方案問題;) – CouchDeveloper

+0

沒有人能想出來,因爲你省略了最重要的細節....你在調用delete之前實際上在第二個線程中投了一個指針。這就是所謂的XY問題(http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。這個問題與線程無關,但你的標題是「從另一個線程刪除對齊的內存」。 – thang

+0

@thang:true。我決定保留這個問題,因爲它顯示了提問者可以忽略的重要細節。所有行業都出現同樣的問題,甚至根據這些看似不重要的特徵發現了一些重大發現,其中大部分在數學和物理學上都很顯着。對於所有閱讀這個問題的人,請從我的錯誤中學習。 – Defd