2017-04-01 242 views
2

我正在維護一些遺留代碼,這些遺留代碼在託管對齊指針類中缺少複製分配構造函數。我加了一個如下(簡化視圖):aligned_alloc複製分配構造函數中的內存塊在釋放時崩潰

#include <iostream> 
#include <cstring> 
#include <stdlib.h> 

template <class T, unsigned AlignB> 
class AlignedPtr { 
private: 
    T *mpBlock; 
    unsigned mBlkSize; 
public: 
    // Size specific Ctor 
    AlignedPtr(unsigned uNum) : 
    mpBlock(static_cast<T*> (aligned_alloc(uNum*sizeof(T), AlignB))), 
    mBlkSize(uNum) {} 
    // Default, empty Ctor 
    AlignedPtr(void) : mpBlock(nullptr), mBlkSize(0) {} 
    // Copy Assignment Ctor 
    AlignedPtr& operator=(const AlignedPtr& x) 
    { 
     T *mpNewBlock(static_cast<T*>(aligned_alloc(x.mBlkSize*sizeof(T), AlignB))); 
     for (size_t index=0; index < x.mBlkSize; index++) { 
      mpNewBlock[index] = x.mpBlock[index]; 
     } 
     free(mpBlock); 
     mpBlock = mpNewBlock; 
     mBlkSize = x.mBlkSize; 
     return *this; 
    } 
    // Destroy managed pointer 
    ~AlignedPtr() { 
     free(mpBlock); 
    } 
}; 

int main(int argc, char *argv[]) 
{ 

    AlignedPtr<float, 16> first_ptr; 
    std::cout << "Pointer Initialized" << std::endl; 

    first_ptr = AlignedPtr<float, 16>(8); 
    std::cout << "Pointer Re-initialized" << std::endl; 

    return 0; 
} 

我的期望是,該方案將正常結束,但是我看到的時候 first_ptr超出範圍(主終端)AlignedPtr析構函數失敗。 我編譯以上無需任何優化爲:

g++ -std=c++11 -g aligned_alloc_bug.cpp -o aab 

在一個Ubuntu的14.04使用g ++ 4.8.2,並獲得以下的運行時錯誤:

Pointer Initialized 
Pointer Re-initialized 
*** Error in `./aab': free(): invalid next size (fast): 0x0000000001cf9080 *** 
Aborted (core dumped) 

有趣的是,當我更換 aligned_alloc malloc posix_memalign因此,程序正常終止。這是一個錯誤 aligned_alloc或我缺少一些基本的東西?

P.S:1)我做了一個簡短的搜索gcc錯誤返回false。 2)建議避免管理原始指針提前得到確認,但我希望能夠幫助解決手頭的問題。

+1

你遵循三規則? –

+0

@Kerrek SB我做過,完整的程序也有自定義拷貝構造函數。 – fsheikh

+0

我認爲這是因爲在賦值運算符中,您正在讀取4字節邊界,但內存分配的是16字節,預計讀取將在16字節邊界。 請嘗試使用valgrind獲取更多信息。 – AquaAsh

回答

0

您按錯誤順序將參數傳遞給aligned_alloc"documentation"

void *aligned_alloc(size_t alignment, size_t size);

這就導致內存崩潰,這時候你打電話free只檢測。

此外,你應該考慮實現一個複製構造函數。這是一個簡單的實施:

AlignedPtr(const AlignedPtr& x) { *this = x; } 
+0

我意識到,但謝謝你的答案,感激地接受。 – fsheikh

1

問題是你有兩個對象指向相同的內存:完成賦值操作符後的匿名對象和first_ptr具有相同的地址。當他們各自的析構函數被調用時.....你可能猜到會發生什麼。

+1

因爲我在拷貝分配中分配新內存我不認爲我的對象指向相同的內存。話雖如此,我已經做了一個更基本的錯誤,即使用aligned_alloc函數的不正確參數順序。我錯誤地認爲aligned_alloc與WIN32 aligned_malloc具有相同的簽名。多麼想念...... – fsheikh

相關問題