みけCATのにっき(仮)
つれづれなるまゝに、日くらし、PCにむかひて、心に移りゆくよしなし事を、そこはかとなく書きつくれば、あやしうこそものぐるほしけれ。
(本当か!?)
出典

malloc系とWin32 APIの併用は悪いか?

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

malloc系とWin32 APIの併用は悪いか?

投稿記事 by みけCAT » 13年前

malloc系とWin32 APIを併用すると不都合が出る可能性があるという噂を聞いた気がするので、
実験してみました。

CODE:

#include 
#include 
#include 

/*bcc用*/
#pragma comment(lib, "comdlg32.lib")

/*
gccでは 
コマンドラインオプションに
-lcomdlg32
を付けてコンパイルすべし 
*/

#define malloc2(s) HeapAlloc(GetProcessHeap(),0,(s))
#define calloc2(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))
#define realloc2(p,s) HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(p),(s))
#define free2(p) HeapFree(GetProcessHeap(),0,(p))

int forqsort(const void* x,const void* y) {
	if(*((int*)x)>*((int*)y))return 1;
	if(*((int*)x)lStructSize=sizeof(OPENFILENAME);
	pofn->hwndOwner=0;
	pofn->lpstrFilter="テキスト(*.txt)\0*.txt\0すべてのファイル(*.*)\0*.*\0\0";
	pofn->nFilterIndex=1;
	pofn->lpstrFile=buf4;
	pofn->nMaxFile=10000;
	pofn->Flags=OFN_HIDEREADONLY | OFN_NOCHANGEDIR |
		OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
	pofn->lpstrDefExt="txt";
	if(!GetSaveFileName(pofn)) {
		MessageBox(0,"GetSaveFileNameエラー","エラー",
			MB_OK | MB_ICONWARNING | MB_TOPMOST);
	} else {
		fp=CreateFile(buf4,GENERIC_WRITE,0,NULL,
			CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
		if(fp==INVALID_HANDLE_VALUE) {
			MessageBox(0,"ファイルが開けません",buf4,
				MB_OK | MB_ICONWARNING | MB_TOPMOST);
		} else {
			WriteFile(fp,buf3,lstrlen(buf3),&written,NULL);
			CloseHandle(fp);
		}
	}
	free(buf);
	free(buf2);
	free(buf3);
	free(buf4);
	free(pofn);
	/*HeapAlloc対標準関数*/
	buf=malloc2(10000);
	buf2=malloc2(10000);
	buf3=malloc2(10000);
	buf5=malloc2(sizeof(int)*10);
	strcpy(buf,"実験");
	strcat(buf,"テスト");
	strcpy(buf2,"testzikken");
	printf("「%s」の長さは%d\n",buf,strlen(buf));
	printf("「%s」の長さは%d\n",buf2,strlen(buf2));
	printf("strcmp(%s,%s)==%d\n",buf,buf2,strcmp(buf,buf2));
	printf("%sから'z'をさがすと%d\n",buf2,(int)(strchr(buf2,'z')-buf2));
	printf("%sから\"kk\"をさがすと%d\n",buf2,(int)(strstr(buf2,"kk")-buf2));
	printf("文字列を入力してください。\n>");
	fgets(buf3,10000,stdin);
	printf("入力:%s",buf3);
	buf5[0]=100;
	buf5[1]=1230;
	buf5[2]=23;
	buf5[3]=545;
	buf5[4]=922;
	buf5[5]=33;
	buf5[6]=1;
	buf5[7]=531;
	buf5[8]=331;
	buf5[9]=999;
	buf5[10]=321;
	qsort(buf5,10,sizeof(int),forqsort);
	printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
		buf5[0],buf5[1],buf5[2],buf5[3],buf5[4],
		buf5[5],buf5[6],buf5[7],buf5[8],buf5[9]);
	free2(buf);
	free2(buf2);
	free2(buf3);
	free2(buf5);
	return 0;
}
結果は
このコードでは不都合は発見できませんでした。
しかし、不都合が起きる可能性は否定できません。
使用の際は注意してください。

ということになります。

冒頭の噂自体覚え違いかも...

ISLe
記事: 2650
登録日時: 13年前

Re: malloc系とWin32 APIの併用は悪いか?

投稿記事 by ISLe » 13年前

#pragma comment(lib, "hoge.lib")
はVC用で
#pragma link "hoge.lib"
がBCC用じゃなかったでしたっけ。

mallocはCRT関数なので、呼び出すCRTランタイムが分散するような使い方をすると不具合が出るというのは聞いたことがありますけど。
DLLでmallocしてEXEでfreeするとか。
C++でDLLを作るときは注意が必要ですね。
単体のEXEでかつ同一スレッドであれば気にしなくても良いのでは。

アバター
へろりくしょん
記事: 92
登録日時: 13年前

Re: malloc系とWin32 APIの併用は悪いか?

投稿記事 by へろりくしょん » 13年前

前も掲示板に書いてましたね。

掲示板でも言いましたが、結論から言うと利用する事自体はなんら問題ありません。 C++ の new や delete も内部では、malloc() free() と同等の物を呼び出していますので、malloc() free() で不具合が出るならば、new delete も使えなくなります。 ちなみに、malloc() free() は内部ではそれぞれ HeapAlloc() HeapFree() を呼び出しています。 さらに言うと、new delete はそれぞれ内部で malloc() free() を呼び出しています。

併用する事が問題だと言えば、HeapAlloc() 関数が返したポインタを free() したりしてはいけません。


> ISLe さん。
> C++でDLLを作るときは注意が必要ですね。
問題的には、C でも同じです。 結局のところ CRT ランタイムを静的リンクした場合、各モジュール毎に CRT が初期化されます。

ISLe
記事: 2650
登録日時: 13年前

Re: malloc系とWin32 APIの併用は悪いか?

投稿記事 by ISLe » 13年前

へろりん さんが書きました:> ISLe さん。
> C++でDLLを作るときは注意が必要ですね。
問題的には、C でも同じです。 結局のところ CRT ランタイムを静的リンクした場合、各モジュール毎に CRT が初期化されます。
C++でクラスを使う場合、malloc/freeの呼び出されるタイミングが見えにくいので気付かずにハマる可能性が高いかなと思ったのですよね。