2017-04-01 4 views
2

管理対象のAligned Pointerクラスにコピーアサインコンストラクタが存在しないレガシーコードを維持しています。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デストラクタが失敗しました:(簡易ビュー)を次のように私は1つを追加しました。私は、任意の最適化をすることなく、上記のコンパイル :私は aligned_allocを交換する際に興味深いことに

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

g++ -std=c++11 -g aligned_alloc_bug.cpp -o aab 
グラムとUbuntuの14.04 ++ 4.8.2で

と次の実行時エラーが発生しますその問題プログラムのmallocまたは posix_memalignが正しく終了します。これは aligned_allocのバグですか、何か基本的なものがありませんか?

P.S:1)偽を返したgccバグを簡単に検索しました。 2)未処理のポインタの管理を避けるようアドバイスすることは事前に認められていますが、手元の問題については助けてください。

+1

3つのルールに従っていますか? –

+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

問題は2つのオブジェクトが同じメモリを指していることです。匿名オブジェクトと完了した代入演算子の後のfirst_ptrは同じアドレスを持っています。彼らのそれぞれのデストラクタが呼び出されると、あなたはおそらく何が起こるかを推測することができます。

+1

私はコピーの割り当てに新しいメモリを割り当てるので、私のオブジェクトは同じメモリを指しているとは思わない。私がもっと基本的な間違いをした、すなわち、aligned_alloc関数の間違った引数の順序を使用していると言いました。私は誤ってalign_allocはWIN32 aligned_mallocと同じ署名を持っていると仮定しました。何があったか分かりません.... – fsheikh

関連する問題