読者です 読者をやめる 読者になる 読者になる

new と delete、malloc と free

因みに、newしたオブジェクトをfreeで解放できるのって、今でもそのまんまなのでしょうか? あれって仕様?

404 Not Found

ひっかかったのはここ。

このためだけにBCCを落としてテストしてみた僕は別に暇人じゃないですよ。
組み込み系のハードとかゲーム機などはメモリの性質とか容量の問題でnewやdeleteを自分で定義しなければならない事が多々あります。
一例ではGBAでは「容量は少ないが高速なメモリ」と「容量は多いが(それでも少ないが)低速なメモリ」があるので、
これらを使い分けるためにmallocを分けるのは普通です。
なので、newやdelete、malloc、freeを自前で書いたりすることはあります。
でも、newで取得してfreeで解放したことはありませんでした。

さて、freeでもきちんとメモリを解放できると聞いて試してみました。
公正を期するために、newの中身はmallocです。配列版のnew delete は面倒なので定義してません。

#include <stdio.h>
#include <stdlib.h>
	
void* operator new (std::size_t size)
{
	printf("new\n");
	return malloc(size);
}

void operator delete (void* p)
{
	printf("delete\n");
	free(p);
}

class CHoge
{
public:
	CHoge() {
		printf("constructor\n");
	}
	~CHoge() {
		printf("destructor\n");
	}
	
private:
	int a;
	int b;
};

void main()
{
	printf("new - delete\n");
	CHoge* hoge = new CHoge();
	delete hoge;
	
	printf("new - free\n");
	hoge = new CHoge();
	free(hoge);
	
	{
		printf("heap\n");
		CHoge hoge;
	}
}

g++だと面倒なので、Borland C++ 5.5.1でやってます。

結果は、


new - delete
new
constructor
destructor
delete


new - free
new
constructor


heap
constructor
destructor

中身はfreeでもdeleteを使わない限りデストラクタは自動で呼び出されませんね。
ただ、「このケースならば」freeで解放しても、メモリ解放前にデストラクタさえ呼び出してあげればメモリの処理としては正当です。
中身としては処理系によっては単に上記のようになっていることもあるので、結論から言えば「メモリは解放」されます。(されることもあります)
でも、やってはだめです。

heapでは再定義したnewは呼び出されていません。
(まぁ、ヒープでなくスタックなんで当たり前)

さぁ、みんなも自前のアロケータにレッツトライ!

結論:C++とは
「俺……不器用ですから」