2017-01-10 7 views
-4

私はちょうどこれを好奇心から試しています。私はコンストラクタとコピーコンストラクタを持つ構造体を持っていて、構造体へのポインタへのメモリ割り当てを実装すると同時に、メインの中でコピーコンストラクタを使って構造体を初期化しようとしています。コピー構造の初期化は問題なく動作しますが、メインリターンの前に解放しようとすると、ヒープにアサーションエラーが発生します。構造体のメモリ割り当てとコピーコンストラクタ

#include <stdio.h> 
    #include <malloc.h> 

    typedef struct tagInfo 
    { 
     int iX; 
     int iY; 

     tagInfo() {}; 

     tagInfo(int x, int y) 
      : iX(x), iY(y) {}; 

     ~tagInfo() {}; 

    }INFO; 

    int main (void) 
    { 
     INFO* pInfo = (INFO*)malloc(sizeof(INFO)); 

     pInfo = &INFO(10, 10); 

     free(pInfo); 

     return 0; 
    } 

アサーションエラーを発生させずに上記のポインタを安全に解放するにはどうすればよいですか?

+4

ないでスパムタグ!これは有効なCコードではありません! – StoryTeller

+0

C++だから、 'new' /' delete'を使うべきです。それに加えて、一時的なメモリアドレスを格納し、それを 'free'で使うのはUBです(' malloc'空間を解放せずにメモリリークを引き起こすことはありません)。 –

+2

CのイディオムをC++コードに混ぜて、その意味をはっきりと理解することなく、混乱を招いています。 C++をうまく学ぶ方法は試行錯誤ではなく、一番下から始め、以前に学んだ言語のバイアスをかけずにアプローチします。初心者のための[良い本を選んでください](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)とステップバイステップでそれを取る。 – StoryTeller

答えて

0

私は基本的な誤解は、コピーコンストラクタは、同じタイプの(既存の)他のオブジェクトに1つのオブジェクトの内容をコピーしていないということだと思うのではなく、初期化された新しいオブジェクトを生成し、コピー元のオブジェクトの内容に基づいて作成されます。

INFOのオブジェクトのメモリを予約する場合はmallocを使用し、pInfoはそのメモリを参照します。

次に、を使用して、INFO型の新しいオブジェクトをヒープ上にインスタンス化し、pInfoがスタック上にあるこのオブジェクトのメモリアドレスを指すようにします。ところで、ポインタpInfomalloc -edアドレスを指していないので、新しいオブジェクトではなく、malloc -edメモリへの参照が失われます。

free(pInfo)は、前にmallocで割り当てられていないメモリアドレスを解放することが重要です。一般的に

INFO* pInfo = new INFO(10, 10); 
... 
delete pInfo; 
+0

ありがとう!これは私が探していた答えのタイプでした!私はC++コードで新しいdeleteを使うべきだと知っていますが、mallocとfreeを使って試してみたいと思います。クールでありがとう! –

2

mallocおよびfreeは、オブジェクトの構築/破壊を処理しないため、C++では使用しないでください。現代のCで


++あなたがユニークな所有権、またはstd::shared_ptrをモデルにしたい場合は、共有所有権モデル化したい場合はstd::unique_ptrを使用する必要があります - これらを「スマートポインタ」と呼ばれ、安全な方法を提供しています割振り/破壊を自動的に処理する動的メモリを管理します。例:

int main (void) 
{ 
    auto pInfo = std::make_unique<INFO>(10, 10); 

    return 0; 
} 

あなたが本当に手動メモリ管理の道を行きたい場合、あなたは(解除+破壊のため)をnew(割り当て+建設のための)deleteを使用する必要があります。例:

int main (void) 
{ 
    INFO* pInfo = new INFO(10, 10); 
    delete pInfo; 

    return 0; 
} 
0

、新しい配置にすることを行うことができますが、それは非常に落胆されています:

実際には、次のやるべき

// allocate 
void* pInfoMem = malloc(sizeof(INFO)); 
// construct 
INFO* pInfo = new(pInfoMem) INFO(10, 10); 

// destruct 
pInfo->INFO::~INFO(); 
// free 
free(pInfoMem); 

をしかし、あなたがする必要があります解放前に手動でデストラクタを呼び出します。(他の回答が言及される)

それだけで行うことがはるかに簡単です:

INFO* pInfo = new INFO(10, 10); 
delete pInfo; 
関連する問題