1 名前:デフォルトの名無しさん mailto:sage [2009/10/20(火) 16:10:55 ] エスケープシーケンスやWin32APIなどの環境依存なものでもOK。 ただしその場合、質問者は必ず環境を書きましょう。 ※sage禁止です(と代々スレに書いてありますが自己判断で)。 【前スレ】 【初心者歓迎】C/C++室 Ver.68【環境依存OK】 pc12.2ch.net/test/read.cgi/tech/1253193779/ 【アップローダー】(質問が長い時はココ使うと便利) kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm codepad.org/ (コンパイルもできるし出力結果も得られるのでお勧め) ◆ソースのインデントについて 半角空白やTABでのインデントはスレに貼ると無くなります。 そのため、アップローダーに上げるのも手ですが直接貼る場合は、 全角空白か に置換すると見栄えだけはよくなります。
758 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 15:26:21 ] CLASS x=y; は xは初期化されず コピーコンストラクタへいくね。 これってたまたま不定値によっては動作がおかしくなりそうだが。 メモリ確保してあるかどうかのフラグの部分でおかしな動作したよ。
759 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 16:03:10 ] >>758 コピーコンストラクタは初期化処理の一種なわけだが。 CLASS の定義がバグってるんじゃね?
760 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 16:10:49 ] CLASS () { flg=0; }やCLASS (int n) { flg=0; }だとflgは確定してるけど コピーコンストラクタは、xが初めて生成されたのか不明で 初期化して良いのかわからないと思ったんです。 コピーコンストラクタは初期化時にしか使われないんですか。 代入と一緒の気がしてました。どちらの場合も対応しないといけない気がしてました。
761 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 16:13:36 ] >>760 コンストラクタはぜんぶ初期化処理。 初期化後のコピーは代入演算子で定義する。
762 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 16:15:04 ] トンクス!
763 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:12:15 ] >749 >test_func(**a) >test_func(*a[y]) >test_func(a[][y]) これはプロトタイプ宣言の話? それとも呼び側? それによって話が変わる。 プロトタイプ宣言ならNを正の整数定数として 1)void func(char **a); 2)void func(char *a[]); 3)void func(char a[][N]); 4)void func(char (*a)[N]); 1と2は全く同じ意味。3と4は全く同じ意味。
764 名前:763 mailto:sage [2009/11/14(土) 19:15:55 ] >749 よく読むと A a[x][y]; を渡したいみたいだね。 それならば、>763の3か4を使う。 1,2ではダメ。
765 名前:763 mailto:sage [2009/11/14(土) 19:23:23 ] >749 何度もすまん。 >A **a >で定義し a[x][y] でメモリを確保して他の関数に引数として渡します aの定義がA **aなら1か2で渡す必要があるが、 それと >a[x][y] でメモリを確保して という部分がつながらない。 やりたいことはこれ? A hoge[x][y]; A (*a)[y] = hoge; それともこれ? A **a; int i; a = malloc(sizeof(A*)*x); for (i = 0; i < x; i++) { a[i] = malloc(sizeof(A) * y); }
766 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:45:18 ] Visual C++ 2005 の環境でファイルを出力するプログラムを作成していますが、 期待通りに出力が行えません。 fprintf_s関数の第2引数の中で、%sを指定していますが、 文字列ではなく、文字として、「C」だけが出力されているようです。 どのようにすれば、文字列「C:\test」が出力されるのか、お分かりの方がおりましたらご教授いただけませんか? -----プログラム----- CString csvFile = _T("C:\\test"); FILE *fileStream; if(_tfopen_s(&fileStream, (LPCTSTR)csvFile, _T("w")) != 0) { return -1; } fprintf_s(fileStream, "あいうえおABC123\r\n"); // あいうえおABC123 fprintf_s(fileStream, "FILE %s\r\n", csvFile); // FILE C:\test → FILE C -----出力結果----- あいうえおABC123 FILE C -----期待している出力結果----- あいうえおABC123 FILE C:\test ※ファイル名を格納してる変数の型は、他の処理でも使用している都合上、変更できません。
767 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:52:03 ] >>766 試してないけど、こうじゃない? _ftprintf_s(fileStream, _T("FILE %s\r\n"), static_cast<LPCTSTR>(csvFile)); 可変長引数に渡す場合にクラスからの暗黙の変換は効かない。 CString 使うなら TCHAR を扱うように統一しないと。 Cスタイルキャストは無しで。
768 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:52:15 ] fprintf_sの引数を(LPCSTR)csvFileにしたらどうだろうか
769 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:54:38 ] >>766 _T マクロ無しにしたら?
770 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:59:58 ] >>767-768 大昔はともかく、いまのCStringはLPCTSTRとして扱ってもかまわないようにできてるから、 この場合問題なのはfprintf_sの"%s"にLPTSTRを渡してることだと思う。 つまりtprintf系の関数を使うのが正しい >>769 それは間違ってる。むしろ至る所に_Tマクロを使うべき
771 名前:766 mailto:sage [2009/11/14(土) 20:09:45 ] 記載いただいた内容で出力することができました。 ありがとうございます。 >>767-770 C言語と比べると全然違うんですね。 Cを少しかじったことがあるので、書けると思っていたら全然でした…。
772 名前:766 mailto:sage [2009/11/14(土) 20:14:34 ] >>770 770さんの書き込みをよくよく読むと出力はできるけど、 これだと正しくないということですか?
773 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:19:02 ] ジェネリックテキスト(_Tマクロとか使うやつ)は使わないほうがいいだろ。 95/98対応する必要があるとかかわいそうな人なんてもう、そうそういない だろうし、ワイド文字列きめうちのほうがトラブルがなくて楽だよ。 それにジェネリックテキスト使っていたって、本当にワイド文字列と マルチバイト文字列の両方に対応できてるコード書けてるかってのもあるし。 両方で動くように意識して書いてるやつなんて少数派だし、_UNICODEありと なしでコンパイルが通るかとか、テストを両方でやってるところとかまで いくと壊滅状態だろうし、事実上ジェネリックテキストなんて機能してないよな。
774 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:21:28 ] >>770 > 大昔はともかく、いまのCStringはLPCTSTRとして扱ってもかまわないようにできてるから、 へー。いまの可変長引数の ... 部分に渡したときも LPCTSTR への暗黙変換が入るのかー。 いったいどういう仕組みで? クラスに operator LPCTSTR () を持ってるだけじゃ、そうはいかないよね?
775 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:25:03 ] >>773 一般的な話ならそれでもいいんだけど、ここでは CString を使ってて、 その型は変えられないと質問者が言ってるんだから _T() が要るだろ。
776 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:25:58 ] >>774 >>770 じゃないけどCSimpleStringT<>のソースは大分前に見たよ データメンバがポインタ1個でvtblもないから メモリレイアウトがTCHAR*と同じになってるんだよ確か
777 名前:768 mailto:sage [2009/11/14(土) 20:29:40 ] よく考えたらLPCSTRへ変換はできなかったかも CStringへ代入はできるけど
778 名前:766 mailto:sage [2009/11/14(土) 20:31:31 ] ごめんなさい。 出力はできるようにはなったのですが、日本語が含んでいるとクエスチョンマークの 文字列が並んでしまいます。 これはやっぱり、上で説明されている変換がうまくいっていないからですか?
779 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:32:44 ] >>778 setlocale(LC_CTYPE, ""); とかやろう!
780 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:32:49 ] >>770 ,776 msdn.microsoft.com/ja-jp/library/awkwbzyc.aspx#_core_using_cstring_objects_with_variable_argument_functions > ... 可変個の引数リストを取る関数に CString オブジェクトを渡すときは、明示的に > 型キャストによる変換を行う必要があります。 やっぱりダメじゃねーか。 www.trickpalace.net/cppll/reference/printf.htm#argument こいつのデマに騙されたんじゃね?
781 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:37:51 ] >>780 #include <cstdio> #include <atlstr.h> int main() { CStringA s = "world"; std::printf("hello, %s\n", s); } うちではこのコードはVC7.1でもVC9でも動くよ まあ推奨はしないってか誰もしてないと思うけど
782 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:41:17 ] >>780 古いATLの利用を考えているならキャストするのが安全だろうけど、 最近のはreinterpret_cast相当の操作でも安全に使えるようにできているから必要はない。 というのはATLの解説書のどれかに書いてあったはず
783 名前:766 mailto:sage [2009/11/14(土) 20:44:59 ] >>779 無事に出力できました。ありがとうございます。 第2引数に何か入れた方が良いのかと思いましたら、そのままでも平気なんですね。
784 名前:781 mailto:sage [2009/11/14(土) 20:52:17 ] どーでもいいけど例が良くなかったね #include <cstdio> #include <atlstr.h> int main() { CStringA s = "world"; std::printf("hello, %s %d\n", s, 123); } これがちゃんと動きます。
785 名前:774 mailto:sage [2009/11/14(土) 21:08:10 ] groups.google.com/group/microsoft.public.vc.mfc/browse_thread/thread/028f80f03d7e253d#msg_7fb2a35dbe1e6ff1 把握した。なるほど。 開発者はがんばって大丈夫なようにしたけど、外向けの仕様としてはキャストが必要と 書かれたままになってるってことだね。ちょっと不憫だな。まぁ古い実装を使ってる場合や 可変長引数の実装方法の違うコンパイラを使う場合にはやっぱり問題になるんで、 しょうがないところかとは思う。 >>780 デマじゃなかったみたいね。
786 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 21:12:38 ] C++でポインタを *で参照はがしした時って、*pointerは参照ということになるの? codepad.org/A8sFOqoG こんな感じで仮想関数使いたい場合、とりあえず思った通りに動くんだけど、 *baseとした時点でBase型に補足されるということはないんですか。
787 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 21:14:29 ] >>786 参照だよ。
788 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 21:17:35 ] わかりました。ありがとうございます。
789 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 14:40:57 ] char 配列が300個連続で0であることを高速で見つけるにはどうすればいいですか。
790 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 14:48:00 ] どういう意味で高速なんだ
791 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 14:56:55 ] CPUの性能を上げれば高速になるよ
792 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 15:11:29 ] ひとつひとつ探すより、memcmp使うとかです。 これは実際に速くなるのですが、500個になると困ります。
793 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 15:12:39 ] 0に限定すれば、memcmpより高速に出来る可能性があると思いますが アセンブラなどわかりません。
794 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 15:15:32 ] O(n)よりは速くならないんだから、あとはCPUのデータシート眺めながらチューンしていくしかないよ
795 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 15:18:52 ] いい方法わかりました。300個目だけ1だったら途中は調べなくて良かったです。
796 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 16:54:40 ] ああもうそれでいいよ、もう来ないでね
797 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 23:16:34 ] >>795 もう少しマシにしようか 300個が0なら150個目を調べる それも0なら75個目と225個目を調べる それも0なら・・・・ 非0である確率が高いならともかく、そうでないなら最初から順々に調べたほうがマシだな
798 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 00:13:52 ] >>797 えっ
799 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 00:20:58 ] データに偏りがあるなら、そういう最適化もあるが、ないなら最初から配列舐めるなぁ。。。
800 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 00:22:43 ] つまらないこと言ってないで、死の行進しとけよ 学生はIT土方になるために必死に勉強しとけ
801 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 01:54:58 ] > これは実際に速くなるのですが、500個になると困ります なんで? そもそも memcmp() 呼び出しが 単純なループ処理より速いってどんな環境? (つーか、まさか毎回if判定してないよな?)
802 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 01:56:41 ] >801 いや普通、ループは毎回判定してるぞw
803 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 02:05:47 ] 例えば ・charではなく、もっと大きな(intとか)のサイズでアクセスし ・毎回判定するのではなく、数十個単位とかを|してから判定することにして ・さらに、場合によってはプリフェッチ的なアクセスの仕方も行う というようなことをすれば、 ・もしかしたら ・あなたの使っているCPUやOS、及びコンパイラと使用ライブラリ限定で ・データによっては ・気休め程度には 速くなる可能性はあるかもね。
804 名前:デフォルトの名無しさん [2009/11/16(月) 11:02:47 ] バーチャルで関数をオーバーライドするときって型を変えたりできないんですか? virtual ってvoidばっかりなのですが
805 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 13:34:53 ] >>804 基本的にはできない。 例外として共変戻り値がある。
806 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 16:46:54 ] グローバル変数はどこから書き換えられるか解らないといった弊害があるから推奨されないかと思うのですが グローバルな定数であれば別にガツガツ使用しても問題ないのでしょうか?
807 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 16:57:15 ] 一番大事なことはそれではないとおもう。 変数がかぶることと思う。 ネームスペースやオブジェクト指向も 変数名、関数名がかぶらなくなることが大事思う。
808 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 16:59:04 ] 変数や関数の生存範囲が小さいほどよい。 公開する部分はのぞく。 グローバル定数も変数も公開するで無ければなるべく範囲を縮める。
809 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 17:02:19 ] 変数を生成するコストを減らすためとかいう理由で グローバル使うのはあほですよ。 大して時間食わないし、変数生成がボトルネックなることはまれ。 時間食ってることが確認できてから変えれば良いんです。 なるべく生存範囲が短くなるようにするのが吉
810 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 17:02:27 ] じゃネームスペースの中にグローバル変数入れときゃいいじゃん
811 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 17:07:16 ] >>805 ありがとうごじあました
812 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 17:08:01 ] 名前の競合なんて屁でもないだろ。 モジュール間でのカプセル化という意味合いの方が大きい。
813 名前:806 mailto:sage [2009/11/16(月) 17:29:33 ] グローバル定数も出来る限り控える方が良いんですね。 ありがとうございます。
814 名前:デフォルトの名無しさん [2009/11/16(月) 18:25:46 ] error C2276: '&' : 仮想関数のアドレスを取ろうとしました。 とか、書き方を変えると、 error C2440: '<function-style-cast>' : 'overloaded-function' から 'float' に変換できません。 とか出ます、仮想関数をはじめていじくっているのでどうすれば良いかわかりません 仮想関数のオーバーライド中では引数のメンバの型を変えてはいけないのですか?
815 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 21:24:18 ] >>814 スレ違い。↓こっち行け。 pc12.2ch.net/test/read.cgi/tech/1187922645/
816 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 21:59:01 ] グローバルスコープがふさわしい物までグローバルから追い出そうとするのも問題だと 個人的には思う つーか、初心者が一番やらかしやすいのは、関数スコープがふさわしい物をファイル スコープに出してしまうことじゃないかと
817 名前:デフォルトの名無しさん [2009/11/16(月) 22:23:03 ] vc++でトランプゲームとか作ろうと思っています。そこで質問が二つあります。 @画像データをPROJECT内に保管しておいて必要な部分を切り取って表示する方法ってありますか? AWIN32とmfcとで方法が違うかもしれませんが、ゲームを作成するのに向いているのはどっちでしょうか? ※開発環境(といえるほどのレベルではないのですが・・・)VISUALSTUDIO2005でvista32bitです。 入門書とかも何冊か読んでみたのですが、自分が求めている情報がズバリ載っているわけではいないので、 質問させていただきました。詳しい方がいらしたらぜひアドバイス願います。
818 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 22:29:58 ] >>817 1、ビットマップの管理方法で違う。APIに任せるなら、loadImageしてBitBltなどのAPIを使う。 自前で管理するなら、配列いじるのと変わらない。が、約束事はある。 2、どっちでも作れるから、作りやすいほう選べ。CかC++か位の違いしかない。どっちにもお約束事はある。
819 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:09:48 ] 環境変数はグローバル変数だから使用禁止 外部からファイル読み込むのもグローバル変数だから使用禁止
820 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:17:27 ] #define HOGE 1 #define HOGE 1 #define HOGE 1 #define HOGE 2 #define HOGE 1 #define HOGE 1 同じ名前の定数を何度も宣言した場合、値が同じうちは何も言われず、 上の場合は1→2と2→1のところでのみ警告が発生するのですが、 これはCやC++の標準の仕様として頼ってしまってもよいものですか? Win32のDLLからエクスポートするクラス群が複数のヘッダに分散していて、 各ヘッダにそれぞれ #ifdef HOGE_EXPORTS #define HOGE_API __declspec(dllexport) #else #define HOGE_API __declspec(dllimport) #endif を入れてしまいたいのです。 それとも、上のものだけが書かれた二重インクルード対策付きヘッダも別に用意して、 各クラスのヘッダからちゃんとインクルードするべきですか?
821 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:19:43 ] >>820 #ifndef HOGE_API #ifdef HOGE_EXPORTS #define HOGE_API __declspec(dllexport) #else #define HOGE_API __declspec(dllimport) #endif #endif
822 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:22:58 ] >>820 同じ名前で内容の全く同じマクロなら何度定義してもいいことになってる。 (厳密にはもう少し複雑な規定があるけど)
823 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:46:26 ] >>821-822 何度定義してもよいということが仕様として存在するのですね。 安心しました。ありがとうございます。
824 名前:デフォルトの名無しさん [2009/11/16(月) 23:49:24 ] 名前: デフォルトの名無しさん E-mail: 内容: 818さんアドバイスありがとうございます。さっそく、プログラムに入力しビルドしてみました。私の力量不足でエラーになってしまいましたが、 loadImage()をいかに使いこなせるかというところが質問の答えのようですね。 A:秀和システムの本:「VisualC++.net逆引き大全」 B:秀和システムの本:「C言語逆引き大全」をぱらぱらとめくってみました。 AのほうにはMFCのところにLoadBitmapを使った方法が載っており、BのほうにはLoadImage()を使う方法が載っていました。 Aのほう CBitmap m_hBitmap; if (m_hBitmap.LoadBitmap(CARD)){ } pDC->DrawState( CPoint(0,0), CSize(100,100), &m_hBitmap; DST_BITMAP); Bのほう HANDLE LoadImage( HINSTANCE hinst,//インスタンスのハンドル LPCTSTR CARD,//イメージの名前または識別子 IMAGE_BITMAP,//イメージのタイプ 100,//希望する幅 100,//希望する高さ LR_DEFAULT //ロードのオプション ); という風なことが書いてあるのですが、Aのほうは、構文エラー )や;があるとかないとか。 Bのほうは、LR_DEFAULTが認識されない識別子だとか、 )や;があるとかないとか。 のエラーが出でしまいます。 これはなぜエラーになってしまうのでしょうか? 理由が分かる方、ぜひアドバイスをお願いいたします。※CARD.bmpという画像ファイルを扱おうとしています。
825 名前:デフォルトの名無しさん [2009/11/16(月) 23:54:46 ] デバッグしてるときに変数に何が入ってるか知りたいのですが_CrtSetBreakAlloc(1162);これしかないですか?
826 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:55:49 ] >>825 VC ならデバッガ使えよ。
827 名前:デフォルトの名無しさん [2009/11/16(月) 23:59:30 ] >>826 効果的な使い方がわからん _CrtSetBreakAlloc(1162);で止めて下に出てるツリーを開いていくやり方以外やったことない 教えて
828 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 00:07:56 ] >>827 _CrtSetBreakAlloc()って知らんからググってみたら、メモリリークの箇所を 調べるみたいなことが書いてあった。 勉強になるなぁ。 変数の中身をみるって、適当にブレイクポイントでとめて、ウオッチで見るとかじゃなくて?
829 名前:デフォルトの名無しさん [2009/11/17(火) 00:10:22 ] おkサンクス、やってみる
830 名前:デフォルトの名無しさん [2009/11/17(火) 00:13:03 ] ああ、普通こうやってやるのか すげえな、サンクス
831 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 05:38:13 ] VCならウォッチ式の設定とか言わず、変数をポイントするだけでもおk。
832 名前:デフォルトの名無しさん [2009/11/17(火) 06:05:27 ] ちょwwVC便利すぎワロタw プログラム暦2年だけど何やってたんだ俺wめっちゃ簡単に割り出せるやんw
833 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 06:32:32 ] vectorの内部で確保されているメモリってclear()でも解放されるの?
834 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 06:36:33 ] 解放されない swapですれよ
835 名前:833 mailto:sage [2009/11/17(火) 06:47:54 ] なるほど、どうも
836 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 07:26:26 ] std::vector<T> v のバッファサイズをバイト単位で取得したい時は、 v.size() * sizeof(T) でいいんでしょうか? 実装によっては何か詰め物でも入っているのではないかと不安なんですが。
837 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 07:40:57 ] vectorのバッファは配列と同じメモリ配置であることが保証されてるから、それでいいよ
838 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 07:54:16 ] >>836 そのサイズを使った操作が何であるかによっては危険な予感がする。
839 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 08:22:29 ] >>837 ありがとうございます。 >>838 内容をファイルに書き出したいんです。
840 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 15:26:13 ] 普通に書き込めばいいじゃん
841 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 17:07:07 ] >>839 ostreamのシフト演算子を定義すればいいと思うよ。 v.size() * sizeof(T) だと、vtableがあったら色々まずい。
842 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 17:21:33 ] バッファサイズに仮想関数テーブルは関係ないだろ
843 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 17:42:42 ] copy(v.begin(), v.end(), ostream_iterator<T>(cout, "\t"); これってさ、Tによっては<<定義しても動作しなくね?
844 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 00:58:34 ] >>843 Tによらずコンパイルエラーになるね。
845 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 01:16:44 ] >>844 いやそういう下らん揚げ足取りはいいから
846 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 01:20:59 ] >>843 動作しそうで動作しない T の例をひとつでも挙げてみてくれ。 そうじゃないと、当たり前のことを聞かれてるだけにしか見えん。
847 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 17:25:58 ] メモリイメージをメモリマップトファイルにmemcpyすれば楽ちん。 ていう考えは古いですか。
848 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 19:48:32 ] 質問させてください。 静的メンバはクラスが存在する前からあるはずなのに、なんでクラスの外で再宣言しなくてはならないんですか?
849 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 20:19:01 ] ヘッダファイルにクラス定義を書いた場合ということでいいのかな? その場合、各翻訳単位の間で重複してクラスの静的変数を定義しない為。 ヘッダファイルにグローバル変数を書いて共有するときも、externで宣言しといてどこかで一度だけ実体の宣言をするよね。
850 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 21:00:32 ] codepad.org/auJS2ura ngの部分でコンパイルエラーが出てしまいます VC++2008EEのエラーメッセージによると引数があいまいだから、ということなんですが どうすれば曖昧さをなくせるのかちょっとわかりません うまいことstd::endlを渡す方法はありませんか?
851 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 21:40:11 ] >>850 endlの型を調べよう
852 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 21:48:59 ] CParent ◇- CChild というように親クラスが子クラスを保持しているとします。 子クラスはプログラム動作中、たくさんnewでメモリを確保します。 プログラム終了時、CChild内でdeleteせず、CParentでだけdeleteすれば、 CChildがそれまで確保してきた領域も伴ってdeleteされるのでしょうか? というのも、ある書籍についてたサンプルコードを見ると、newしまくりなのに、 それらがdeleteされる記述がぜんぜんないんです・・・ 最も最上位のクラス(他の下位クラスを保持している)を最後にdeleteしてるところ くらいしか考えられない・・・ よろしくお願いします。 m(_ _)m
853 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 21:51:28 ] メモリリークしちゃうね とりあえずその書籍の名前を
854 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 21:56:05 ] スマートポインタ使ってたらそう見えるかもしれない
855 名前:852 mailto:sage [2009/11/18(水) 22:01:00 ] >>853 「3D格闘ゲームプログラミング」という本です。 不思議なことに、サンプルのVC++プログクトでビルド実行してプログラムを終了させたとき、 リークがある場合にVC++のログ出力に出てくるメモリリークバイト数が出て来ず、 正常終了できたかに見えます・・・ >>854 スマートポインタを使っているようにも見えません・・・ 一例として ヘッダファイル内 char* xxx C++ファイル内 xxx = new char[ strlen( yyy ) + 1 ]; で、xxxはどこでもdeleteされていません。 VC++上でソリューション内を検索もしましたが見つかりませんでした・・・
856 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 22:09:26 ] 別の変数に代入されてどっかで解放されてるんじゃないの
857 名前:852 mailto:sage [2009/11/18(水) 22:21:50 ] >>856 追跡してみましたが、見当たらず・・・ そういえば、newされたやつの多くはSTLのvectorにpush_back()されています。 ヘッダーファイル内 #include <vector> using namespace std; vector<CChild*> Child; C++ファイル内 Child.push_back( new CChild() ); 何か関係があるのでしょうか? このvectorはポインタのコンテナになっていて、やはりどこかでそれらのポインタの先にある 実体領域を解放してやる必要がありますよね?
858 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 22:24:30 ] そういわれても実際にコードを見られないんじゃ何とも答えられん。
859 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 22:26:10 ] Childが死ぬときに開放してるんだろ。 とりあえずステップ実行して、本当に開放されないのか一行ずつ確認してください。
860 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 23:01:08 ] >>848 クラスの外に書くのは、宣言ではなく定義。
861 名前:852 mailto:sage [2009/11/18(水) 23:01:49 ] 作者さんのページで、どうも関係のありそうな記述を発見しました。 ttp://cgi32.plala.or.jp/higpen/book/shtPro/qa.shtml#program10 違う書籍の違うプログラム部のところの話ですが、 たぶん、これと同じことだと思います。 なんと、解放はOSに任せられるとのこと。 あまり行儀は良くないですよね^^; よほどプログラムの動きやOSのメモリ管理に精通してないととてもできないw でも勉強になりました。 みなさん、ありがとうございました。 m(_ _)m
862 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 23:19:45 ] なんか苦しい言い訳に見えるな。百歩譲ってそれが「正しい」方法だとして、 プログラミングを勉強する本にそういう書き方をするのはいかがなものだろうか…
863 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 23:26:33 ] 質問を勝手に自分の理解できる範囲の問題に解釈し直すのはいくない
864 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 00:25:35 ] >>861 そんなこと言ってると、ごちゃごちゃ言ってないで std::vector 使えカス、ってバカにされちゃうよ。
865 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 00:29:15 ] VC6 時代の古い本ならしょうがないか、と思ったけどそのリンク先 Q&A の 日付見たらごく最近なのな。著者が不勉強なんだろうと思う。
866 名前:852 mailto:sage [2009/11/19(木) 00:57:36 ] >>864 多態を使わなければ、クラスのインスタンスのvectorを使ってもOKみたいですね。 vector<CXXX> xxx; CXXX x; xxx.push_back( x ); // xxxコンテナへのコピーになる これだったら、領域確保はvectorがしてくれるので楽ちんですね。 これでいきます。 ありがとうございました。
867 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 01:51:30 ] コンストラクタ初期化子を使わないと駄目だっていうけど、初期化の順番を明示したい場合はコンストラクタ関数内で初期化してもいいよね?俺悪くないよね?
868 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 01:53:45 ] どうでもいい。
869 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 02:41:35 ] >>867 IDE のインテリジェンス機能が動かなくてもいいならそれでもいいよ
870 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 02:57:34 ] コンパイル時にクラスや構造体のメンバのオフセットアドレスを得る方法ってあります?
871 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 03:00:38 ] offsetof
872 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 03:30:02 ] >>871 それだったか、感謝。
873 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 08:16:43 ] >>861 それはメモリリークそのものだろw そんなレベルで本書くなよ…
874 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 08:47:42 ] よく読んでないけど 説明は下手糞だけど、最初に確保したメモリをプールしておいて使いまわす手法じゃないの? だとしたら、そういうのはリークとは呼ばないよ。 MoreEffectiveC++にもちゃんと書いてあるし。 違ったらごめんな。
875 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 08:48:47 ] ×使いまわす手法 ○使いまわして、最後まで(プログラムのコード内では)解放しない手法
876 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 08:57:25 ] メモリなら最悪リークしてても、プロセス終了時に解放されますよって話だろ? まぁメモリ以外のリソースだと解放してくれなかったりすることもあるけど。
877 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 09:29:20 ] だから、たとえ解放処理(free/delete)をしていないとしても ちゃんと管理できているものは「リーク」とは呼ばないって話だよ。
878 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 09:34:03 ] >>867 初期化の順番はメンバの宣言順と決まっている。 コンストラクタの記述方法で明示などできない。 無知なオマエ悪い。
879 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 09:38:59 ] >>874-875 よく読んでみなよ。 >>861 のやつは使いまわしてすらいない。
880 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 09:39:33 ] 最後にOS任せで消滅させて、途中どんなに肥大してもシラネ、ってのは管理ではなく リークと呼ぶだろw
881 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 10:06:29 ] >>879 だから、 >タスク用メモリはプログラムの終了時まで解放しない が、「deleteを呼ばない」という意味ではなく 「プログラム終了まで使用している領域である」という意味ではないか、と言っている。 使用している(管理している)領域なんだから、deleteするコードが無くても問題ない。 もちろん、その「タスク」が、プログラムの中で際限なく増えていく (あるいそのタスクを指す領域を見失っている)ようなら問題だが 俺はコードを読んでないので、どういう構造なのかは明言できない。 だから、「よく読んでないが」「説明は下手糞」と書いた。 そして、(明示的にdeleteを呼んで無くても)管理下にあるものはリークとは呼ばない。これは確実。
882 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 10:07:54 ] で、使いまわしているかどうかは問題の本質じゃない。 管理下にあるかどうかが本質。
883 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 10:23:05 ] >>881-882 よく読んでみなよ。 >>861 のやつは管理下にすらない。 「タスク」じゃなくて char 配列のほうな。ローカルな生ポインタ変数に入れて、 そのままスコープアウトしちゃってるみたい。 当たり前の主張を長文で繰り返す前に、「よく読んでない」と自分でわかってる なら元記事をよく読めと。
884 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 10:36:43 ] このサンプルでは以下の理由から、new char[]で確保した領域を明示的に解放する処理を省略しています。同様の理由で、他にもメモリの破棄を省略している部分があります。 * サンプルプログラムをなるべくシンプルにしたい * タスク用メモリはプログラムの終了時まで解放しない * プログラム終了時にはOSがプログラムに関連するメモリを解放してくれる * 一般にdeleteで解放したメモリはOSには返却されず、プログラムの内部に保持されたままとなるため、タスクリストの場合は実行中に解放する意味が薄い 上記の理由から、メモリを解放しなくても動作に問題はなく、他のプログラムへの影響もありません。推奨される方法としては、例えばタスクリストのデストラクタ ~CTaskList() を記述して、その中で上記のバッファを、 delete [] buf; のように解放します。この場合、bufをメンバ変数にしておく必要もあります。
885 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 10:49:18 ] 「禁無断転載」と明記された記事を意味もなく転載するのはおすすめしない。 せめて引用の形にとどめておけ。
886 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 12:04:53 ] っていうか、いかなる場合でも 確保したメモリちゃんと解放すればいいんだよ。 メモリを解放するデメリットなんてないだろ? もし、終了時に遅くなるとかいう話なら 「終了処理を速くするテクニック」として使えばいいだけの話。 それが必要になるときがくれば使え
887 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 12:08:20 ] >deleteで解放したメモリはOSには返却されず、プログラムの内部に保持されたままとなるため、 再利用されるとか考えないのかね?
888 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 12:13:50 ] その機構部分は仮に良い という立場だったとして new と delete がペアになっていない構造だから 別コードで本当にリークさせてる部分の追跡をするのに面倒じゃね?
889 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 13:33:47 ] deleteしてもメモリ返せないの?なんで?じゃあどうすんの?
890 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 13:34:17 ] どうもしない
891 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 14:50:59 ] なんで、サンプルで手抜きをするのかねぇ? deleteなんて一行増えるだけじゃん。 いちいち言い訳を書くよりも deleteを書けばいいじゃんか。
892 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 14:52:56 ] deleteしてもメモリ返せないの?なんで?じゃあどうすんの?
893 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 15:02:56 ] >>892 マジレスはしてあげないよw
894 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 15:03:31 ] どうもしない newしたときに再利用されるだろうな
895 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 15:34:47 ] サンプルをシンプルにしたいからって理由で無茶すんなよなぁw リーク検出とか使えなくなりそうだしなぁ
896 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 16:12:06 ] >>893 無知は黙ってろハゲ
897 名前:852 mailto:sage [2009/11/19(木) 19:05:22 ] 物議を醸していますね^^; 作者の方は東大を出ておられますが、地頭が良いとこういう考え方になるのでしょうか・・・ ともあれ、今はnew、deleteはセットで書くよう心がけたいですね。
898 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 19:44:29 ] deleteするしないはコードの本質でないと判断したんだろう。 まぁ論文ならそれでいいんだろうが、一般向け、しかも初心者が食いつきやすいゲームプログラミングの書籍で それをやると何も考えずに模倣する馬鹿が出てきてしまうから、やめた方がいいと思うがな。
899 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 19:46:38 ] メモリリークしてたらだめだ 実測しむ
900 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 19:49:53 ] 1Mのメモリーリークが100回起これば100M消費する プログラムが終了すればOSが回収するが、 動いている間はそのまま。
901 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 21:10:32 ] 東大出てても糞コード書く奴はどうしようもないよ しかも学歴が高いせいで自信だけはあるから逆にめんどい
902 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 21:34:57 ] Cなら終了時まで解放しないメモリをfreeしないっていう層は結構いるから その亜流なんだろう
903 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 22:48:47 ] >>897 もちろんnew/deleteをセットで書いてもいいが それよりスマートポインタを使うんだ
904 名前:852 mailto:sage [2009/11/19(木) 23:01:20 ] >>903 COMでCComPtrを使ったことがあって、めちゃくちゃ便利でした。 自前のを作るとなると・・・うまく組めるかちょっと心配です(汗) でも便利なのはたしかなので、勉強してみます。 ありがとうございます。
905 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 23:04:08 ] shared_ptr < ・・・
906 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 23:36:09 ] BCB5+Win環境です char配列などを頻繁にnew・deleatする際、どっかのサイトで win環境では固定サイズでnewしたほうが断片化しにくいと 書いてあったような気がするのですか 本当でしょうか? あまりnewをいじりたくないので気になります
907 名前:852 mailto:sage [2009/11/19(木) 23:45:36 ] >>905 おおお! こんな便利なものがあったのですか! VC++2008ならstd::で使えるそうですが、自分は2005ですね・・・ しかし、boostを導入すれば使えますね。 CComPtrと同じように使えるのであれば、慣れていますし、導入もし易そうです。 教えてくださって、ありがとうございました!
908 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 23:54:42 ] std::multimap<int, int> test; test[0] = 1 test[0] = 2 test[0] = 3 ...いろいろ代入... としたときに、 std::multimap<int, int>::iteartor begin = test.lower_bound(0); std::multimap<int, int>::iteartor end = test.lower_bound(0); std::multimap<int, int>::iteartor it; for (it=begin; it!=end; ++it) printf("%d", it->second); で得られる結果は必ず 1, 2, 3 の順番になると保障されていますか?
909 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 23:56:21 ] std::multimap<int, int>::iteartor end = test.upper_bound(0); でしたすみません
910 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 00:10:27 ] されてません。
911 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 01:05:18 ] >>906 new の回数を減らせば断片が減る(断片化しにくい)のはあたりまえ。 それ以前に、ほんとうに断片化による悪影響で困ってるのか? Windows 上では、特にギガバイト単位のメモリ空間(アドレス空間)があたりまえな 最近の一般的な環境ではかなり稀なケースになると思うんだが。
912 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:12:17 ] >>901 実際に動作させるコードでdeleteするしないの問題と、解説書でdeleteを省略するしないの問題を 区別できていないお前は多分低学歴なんだろうな
913 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:13:44 ] 実際に動作させるコードからかけ離れたコードを提示する解説書がそもそも問題 削っていい部分とそうでない部分があるが、こういうのを削っていいと思うようなら 糞コードと言われても仕方ない
914 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:15:13 ] ま、万人向けの本でやっちゃだめだよな。
915 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:17:50 ] ぶっちゃけこんなアホなコードを本気で擁護する奴なんて本人以外いるの?w
916 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:28:12 ] >>912 省略したほうがシンプルでいいと思ったけど結局は言い訳がましい Q&A を書くハメに なったってことで、解説書のための判断としても失敗だろ。 紙面の問題を考えても、 std::vector 使っとけば #include が1行増えるかもしれないって 程度だし。
917 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:38:29 ] まぁ、全てを綺麗に書くことが正義という言語でもないし、本当に必要ならば手を汚す こともあるけどな。>>884 は手を染める理由としては全く不足だと思うが。 とりあえず買っちゃいけない類の本ではあるな。良い初心者は混乱し、悪い初心者は 汚れる。中級者以上なら他に投資すべき本があるだろう。
918 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 03:10:28 ] 確保したハンドルやリソースを開放しないままプログラムが終了しても 言語やOSの仕様でプログラム終了時に確実に回収することがわかっていて かつ、リークしないこともわかっているなら、別に開放しないまま終わってもいいじゃないか。^^ たとえば、 int main() { int* i = new int; } 上のプログラムはメモリリークしていない。 なぜなら、ポインタが消失して削除不能になるのはプログラムが終了する瞬間であり その直後にはすべてのリソースが回収されることが仕様で決まっているからだ^−^ 美学とかいうなら別だが。
919 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 03:28:08 ] classのお作法を守ってないからでしょ。後で書いた方?は直してるみたいだし
920 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 03:37:02 ] あえてdeleteしない、なんて初心者向け解説本でやるべきじゃないよな。 「3D格闘ゲーム」ってことだから、おそらくキャラクタ2体分のオブジェクトを作って プログラム終了まで開放しない、みたいなコードだと思うんだけど、 読者がそこから拡張していこうとした途端にメモリリークを起こす気がする。
921 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 06:08:35 ] 繰り返しのnewがでたらやばいんだって。
922 名前:852 mailto:sage [2009/11/20(金) 08:12:39 ] この本はdelete問題の他にも、ちょっと「?」というか、もっと効率的な方法があるのでは?と 思ってしまうようなところもあるのですが、 アニメーション付Xファイルの読み込み、およびそれをゲーム中でアニメーションさせるところの 解説はものすごく参考になっています。 今までいくつかのWebサイトでそれを解説しているところも見てきましたが、 この本の内容が一番分かり易かったです。 アニメーションのための本質的なところ(動作、仕様レベル)だけ抽出して、 実装に向けたクラス設計や仕様は自分で改めて考えてからコーディングしていったら良いと思いました。
923 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 09:00:43 ] 分かりやすいように見えても、どこに罠が仕込まれてるか分からんのではなぁ
924 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 09:06:43 ] 糞コードを本にして売るほうも、本に書いてあるコードを吟味せずにそのまま使うほうもアホ
925 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 09:12:37 ] Amazonレビューを見たら、そのアニメーションの解説も参考にするとまずそうな 雰囲気に見えるが… まぁ、買っちまったら何とか活用したいんだろうけどなぁ… つーかサンプルプログラムの作り方もひどそうだ ゲームがコマンドライン引数でviewerに変わるらしいが、やってみたくてやっちゃった のかな、使い勝手とか全然考えずにw もちろん「コマンドラインの処理サンプルを入れたかったので」とか言い訳はいくら でも思いつくが
926 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 10:25:39 ] DLLとEXEでは使ってるアドレス空間が違うとのことなんですがポインタがどっちのアドレス空間に属しているかしらべる方法はありますか?
927 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 11:15:06 ] >>918 そういう特殊な事例でしか当てはまらないものは 特殊な例としてあげればいいんだよ。 int foo() { int* i = new int; } 関数名を変えただけで、この処理はリークしているかもしれない。 int main() { MyClass* i = new MyClass; } クラス名を変えただけだが、delete時にファイル削除とかしているかもしれない。 な? コードは修正されるもの。 そういうときに自分で罠を仕掛けてどうする。
928 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 11:33:29 ] >>926 できるでしょうね
929 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 11:44:16 ] 連続稼働させるものや、多くメモリ確保する物では メモリリークは致命的。 512K確保する関数を200回呼び出せば、合計で1ギガ消費する。 deleteしないでこれを放置するやつは超初心者
930 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 11:45:57 ] ブラウザはよくリークする
931 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 13:23:01 ] >>918 それはメモリリークだよ。 もう使わないからdeleteしていいのにdeleteしないままプロセス終了を迎えたら、それはメモリリーク。 「プロセス終了時に把握できているメモリリークがあっても特に問題無い」には反論しないけど、 「リークじゃない」はおかしい。 そのプログラムがメモリリークしてないなら、メモリリークしてるプログラムなんてこの世に無いよ。
932 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 13:44:20 ] 目立ってメモリリークしなければ無視でも良いけどね。 たとえば、4バイトのメモリリークで128M=2^24バイトたまるには、 400万回やらないといけない。 10秒に一回起こったとしても、400万回するには一年半ほどかかる。、
933 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 14:14:47 ] まぁ、習慣的にリーク対策しないと、大事なとき忘れるし、コードの再利用したときも不具合を生みやすい。 俺は基本的にnewしないでスタックに確保するから、そういう問題はほとんどないな。 はやくスマートポインタが使いたいぜ。
934 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 14:18:40 ] vcでメモリリーク検出できるからそれでいいよ。 わずかに残ったとしても致命的にはなりにくい。 なったら変更すればいいし。
935 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 14:25:54 ] シングルトンな奴は基本 delete しねぇなぁ、俺は。
936 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:10:46 ] new deleteはコンパイラ依存していますか? 別のコンパイラで確保したメモリを、VCでdeleteは出来ませんか?
937 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:27:03 ] >>936 別のコンパイラどころか、同じコンパイラでも異なるDLLでnewしたオブジェクトをdeleteすることは 原則としてできません。(MFCの拡張DLLは別)
938 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:34:39 ] new deleteはオーバーロードだってできるからな。 あえてやるひとはいないだろうけど、 自分以外誰にも使えないnewの実装だってありえる。
939 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:37:30 ] そうだったんですか。 そうだとすると、DLLがメモリ確保してリターンしたら解放不可能になるんですか。
940 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:40:48 ] んなこたーない メモリを確保する関数 と 確保したメモリを開放する関数 を用意しときゃよい fopen() と fclose() の関係
941 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:49:42 ] DLL が提供しているのが newしたポインタを戻すだけで その後始末の delete は呼び出し側がやってね という造りはマズイ ってこと DLL は 自前newしたものを戻すつもりなら それを受けて delete する部分も提供すべき # で、後者を記述するのに安全を見て >>926 で保険かけたいんだけど… どうすれば良い? # という流れになるのかな?
942 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:50:14 ] Windows APIだとCreateなんたらでハンドル作ったら、 CloseHandleよびだしたりするね。
943 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:55:17 ] ----DLL---- typedef void *(*dll_alloc_t)(void *(*)(size_t), size_t); __declspec(dllexport) void *dll_alloc(void *(*)(size_t), size_t); void *dll_alloc(void *(*alloc)(size_t), size_t s) { return alloc(s); } ----EXE---- dll_alloc_t dll_alloc = (dll_alloc_t)GetProcAddres(hDLL, "dll_alloc"); void *p = dll_alloc(malloc, size); こうした場合メモリはどっちに確保されるの?
944 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 16:03:32 ] 内部実装に詳しいわけじゃないから適当にいうけど、 EXEから呼ばれるDLLがリンクしているalloc関数を実装しているライブラリ・・・が OSにメモリ割り当てを要求して、OSが返してくれる適当なメモリ領域・・・・の 一部分をallocが適当に調節して返すんだから、 どっかOSが適当に決めた場所なんじゃないの?
945 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 16:37:27 ] VC++だとこうなったが・・・ //DLL.c #include <stddef.h> __declspec(dllexport) void *dll_alloc(void *(*alloc)(size_t), size_t size) { return alloc(size); } //Main.c #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <string.h> typedef void *(*dll_alloc_t)(void *(*)(size_t), size_t); int main(void) { HINSTANCE hDLL = LoadLibrary("DLL"); dll_alloc_t dll_alloc = (dll_alloc_t)GetProcAddress(hDLL, "dll_alloc"); char *p = (char *)dll_alloc(malloc, 10); strcpy(p, "hello!"); puts(p); FreeLibrary(hDLL); puts(p); free(p); puts(p); return 0; } //OUT hello! hello! ンンンンンンンンンンンンンンンン-
946 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 17:01:03 ] これで良いみたいだな。winapi使った // DLL #include <windows.h> #include <stdio.h> extern "C" WINAPI void memo( HANDLE hd, char *&p ) { p = (char*) HeapAlloc(hd, HEAP_ZERO_MEMORY, 1<<20); strcpy(p,"hgujyguyguyguyguby"); printf("%s\n",p); } // EXE #include <windows.h> #include <stdio.h> typedef void (WINAPI *FNC)(HANDLE , char*& ); int main(){ HINSTANCE hd= LoadLibrary("dll.dll"); FNC memo = (FNC)GetProcAddress(hd, "memo"); HANDLE hHeap = HeapCreate(NULL, 0, 0); char *p; memo(hHeap, p); printf("%s\n",p); HeapFree(hHeap, NULL, p); HeapDestroy(hHeap); getchar(); }
947 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 17:48:12 ] C言語でWin32APIをさわっています。winbase.hに WINBASEAPI VOID WINAPI OutputDebugStringA(__in LPCSTR lpOutputString); と書いてあったんですが__inって何ですか?
948 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 17:53:49 ] msdn.microsoft.com/en-us/library/aa383701 (VS.85).aspx まずは自分で調べてほしい。
949 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 18:38:48 ] DLLとメモリのやりとりを確実にするには、(HANDLE, char*)のペアで 扱うのが良いと思いますが、 一方ではペアとして、一方ではchar*と自動的にキャストさせる方法はありますか。
950 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 18:43:12 ] >>948 縛りの弱いconstのようなものでしょうか? SAL解釈と言うんですね ググったんですがなかなかそこまでたどり着けませんでした
951 名前:949 mailto:sage [2009/11/20(金) 18:43:43 ] 自作関数だと、ペアでもchar*でも受け入れるように出来ますけど 自作ではない関数に対しても、自動でキャストして通るように出来れば便利なんですが。
952 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 18:46:22 ] 何でもかんでも暗黙キャストしてると後ですごい不安になる
953 名前:950 mailto:sage [2009/11/20(金) 18:46:57 ] >SAL解釈と言うんですね SAL注釈ですね、間違えました
954 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 18:47:31 ] double - int みたいな暗黙キャストを実現する方法はないですか?
955 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 19:00:34 ] >>949 ごめん、なんでハンドルが出て来るのか分からない。
956 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 19:05:55 ] >>946 の HANDLE hHeap = HeapCreate(NULL, 0, 0); と char *p; のペアを char*型のように扱いたいって事なんです。 無理でしょうか?
957 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 19:33:10 ] std::vector< boost::shared_ptr< T > > と boost::ptr_vector< T > はどちらを使っても同じでしょうか? 「一方ではこれができないから注意!」とかあったら教えてください m(_ _)m
958 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 19:45:50 ] 猿介錯
959 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 19:52:27 ] よくわからないならvector<shared_ptr<T>>のほう使っとけ
960 名前:957 mailto:sage [2009/11/20(金) 20:33:38 ] >>959 分かりました! ありがとうございます!
961 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 20:43:50 ] shared_ptrって余分に一回メモリ確保してない?あれは何なの?
962 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 21:00:30 ] 参照回数を共有するため、その変数を確保してる。
963 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 21:00:34 ] 関数の戻り値は、通常 値渡しですが 100Mほどのデータをもつクラスでも値渡しになりますか。 (値渡しのコストを下げるために) もし100Mがポインタに入っていて、 auto変数でリターンするとデストラクタが働いてメモリは解放されてしまいますが newで確保した物をリターンすると、それは解放できなくなりますか。
964 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 21:03:27 ] 戻り値にクラスを持ってこずに引数を参照渡しにすればいいのですが 変数を用意する事無しに、リターンがクラスになっていると便利なことがあるんです。
965 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 21:27:13 ] 戻り値がクラスというのは意味不明。 オブジェクトを返すとして、たとえば、 LARGE func() { return * new LARGE; } というのは結局コピーしてるし、メモリが回収不能になるので、絶対にだめ。 LARGE & func( LARGE & inout ) { //LARGEを使った処理。 return inout; } として、外で大きなデータを用意してやるか、 funcで全く新しいオブジェクトを作成したいと言うなら、newしてポインタを返せばよい。
966 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 21:38:14 ] >>965 Qtでこんな関数をオーバーロードしろって言われてるんだけど、 何を返せばいいの? QSize sizeHint(引数略) { return ? }
967 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:05:09 ] QSizeオブジェクトでいいと思うよ。
968 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:16:32 ] え? でも>>965 ・・・
969 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:18:16 ] QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const あとこんなのもあるんですが・・・
970 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:20:50 ] QSizeオブジェクトを返すことが、ライブラリによって強制されてるんだから、従えよ。
971 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:21:12 ] お前が何を聞きたいのかわからない
972 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:23:15 ] > というのは結局コピーしてるし、メモリが回収不能になるので、絶対にだめ。 ってかいてるじゃないですか
973 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:23:59 ] QSizeって大きくないでしょ。(というか100Mというサイズはどこから) 値で返しても何も問題ないじゃん。
974 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:40:44 ] それ以前に QSize sizeHint(引数略) をオーバーロードするのに、 戻り値を参照やポインタにはできんだろ。 オーバーロードのルールを思い出すのだ。
975 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:42:16 ] いや、戻り値を変えられないのはオーバーライドじゃろ。
976 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:47:28 ] たまにいるよね(値|参照)(返し|渡し)の違いがわからない人って まあわからないようなレベルでできることなんて高が知れてるから分かるまで値返しでいいんじゃないかな
977 名前:デフォルトの名無しさん [2009/11/21(土) 05:12:37 ] インテルコンパイラでコンパイルしている場合に#ifdef分岐させたい場合、 #ifdefの後何を書けばよいのでしょうか?
978 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 05:16:39 ] defined (__ICC)
979 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 05:35:04 ] archives.postgresql.org/pgsql-committers/2007-08/msg00120.php Apparently icc doesn't always define __ICC, and it's more correct to check for __INTEL_COMPILER. Per report from Dirk Tilger. Not back-patched since I don't fully trust it yet ...
980 名前:デフォルトの名無しさん [2009/11/21(土) 05:37:04 ] オンラインで見られて、プログラム未経験者向けのC++の講座って、ロベール以外に何がありますか?
981 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 09:58:59 ] >>980 こことか見てた Programing Place ttp://www.geocities.jp/ky_webid/index_old.html
982 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 12:57:09 ] ロベールの翻訳は分かりやすい
983 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 13:17:19 ] >>982 どこが翻訳なんですか?
984 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 16:38:20 ] 自作クラスをcoutで出力するにはどうすれば良いですか?
985 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 16:41:43 ] ここみたら無理そうなことがわかりました 諦めました www.jah.ne.jp/~naoyuki/Writings/ExtIos.html
986 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 17:00:01 ] そのページに書いてあるのは標準ストリームクラスの拡張であって、 君がやりたいのは標準ストリームクラスで自作クラスを出力することでしょ? まったくの別件だと思うよ。 君が勉強すべきなのは、演算子オーバーロード。
987 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 17:06:21 ] サンクス!です
988 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 17:27:13 ] これで出来ることはわかりましたが、char*からsize分だけ渡すにはどうすればいいですか。 std::ostream& operator<<(std::ostream& os, const ustring& x) { return (os<<*****): }
989 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:15:23 ] >>983 多くのプログラミング書籍が洋書からの翻訳であることを揶揄したジョークだろう よく書かれるコピペみたいなものだ
990 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:22:42 ] >>988 C/C++言語の仕様で\0まで出力だと思うので、任意の場所に\0を突っ込んでやればいいと思うよ。 バッファのオーバーランやアンダーランに気をつけて。
991 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:30:02 ] \0があっても標準出力へ渡したいんです… ustringはchar*とintのペアです。 STLは使えません。 あと、別の質問があるのですが。 クラスのメンバ関数で、 char* & operator [] ( int n ) { return &(ch[n]); } だとエラーになります。 char* & operator [] ( int n ) { static char*p=&(ch[n]); return p; } だと通るのですが 同時にアクセス来た場合に困ります。 衝突しない参照渡しはどうやればいいですか。STL stringみてもよくわかりません。
992 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:39:11 ] >>991 変数でもないものの参照を返したいとか訳分からん 値を返すんだと不都合なの?
993 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:39:28 ] >991 やりたい事は本当に operator[] で char* & を返す事なのか? ch って char* なんだよな? string と名のつく型で operator[] だったら普通 char& が返ると思うんだが。
994 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:43:27 ] 値で返すと memcpy(buf, &str[0], size); が実行できないんです。 error メモリ上に配置されなければならない がでます。 static char*の参照返しだと出ません。
995 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:44:35 ] わかりました。間違えてました。>>993 さんのご指摘通り間違えしてました。
996 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 19:05:39 ] >>988 たのみます char* , intが与えられたときに標準出力( << )に\0を含む文字列を出力したいです。
997 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 19:31:43 ] >>996 その前に、どういうインタフェースにしたいのか考えれ。 operator<< をオーバーロードすると cout << yourclass << endl; のような書き方ができるわけだが、 char*とintの二つのパラメータを与えるなら そういう書き方はできなくなる。 それとも const char * operator()( int ) みたいなメンバを持たせて cout << yourclass( 文字数 ) << endl; とかけるようにでもするかい^^
998 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 19:37:28 ] stringは、string(ch, size)で、\0を含む文字列を cout<<に渡せるじゃないですか。 この実装はどうやってるのかわかりたいです。
999 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 19:45:50 ] templateクラスのメソッドってnewしたら使われてなくても全部実体化しちゃう?
1000 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 20:03:01 ] >>998 コンストラクタの話とoperator<<の話がごっちゃになってるじゃないか^^
1001 名前:1001 [Over 1000 Thread] このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。