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でのインデントはスレに貼ると無くなります。 そのため、アップローダーに上げるのも手ですが直接貼る場合は、 全角空白か に置換すると見栄えだけはよくなります。
409 名前:Java厨 mailto:sage [2009/10/29(木) 20:20:11 ] ガベコレあるからメモリリークしても問題ないもんね
410 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 20:21:26 ] >>409 何も考えずに shared_ptr 使えばいいよ
411 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 20:31:34 ] >>395 とりあえず、こだわりが無いなら素直にVC++2008EEにした方がいいと思うが。 昔はWindowsで比較的素直に使えるフリーコンパイラがBCCくらいしか無かったが、 今はVC++EEがあって、ぶっちゃけBCCより遙かにまともに動くし、Windowsだと VC++以外全く考えられてないのも普通だし。
412 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 20:48:56 ] イテレータでvectorをfor文でbeginからendまで読んでいる途中でそのvectorにpush_backしても問題ないですか
413 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 20:55:11 ] >>403 はむしろ、C++のTest t1;の意味を誤解してそうな気がする。 C++の場合、これで作られるのは参照じゃなくて値(インスタンス)。つまり、 そのソースではインスタンスが二個作られてる。 Test *t2 = new Test();の方は、new Test()がヒープ上にインスタンスを生成して、 それを指すポインタを返す。で、t2というポインタ変数に代入する。 C++では、ヒープ上に生成したインスタンスは必ずdeleteしなきゃ駄目なので、 delete t2;をしないとリークする。これが忘れやすくて危険だから、専用のクラスを 作って、コンストラクタでポインタを記憶してデストラクタでdelete、という手法が ある。いわゆるスマートポインタで、有名なのはshared_ptr。既に標準ライブラリに 入ってる処理系も多数あり。無くてもBoostライブラリを入れればおk。 これをポインタ以外に広げて、例えばファイルハンドルをコンストラクタで生成や 記憶などして、デストラクタでクローズ、というように、資源の確保と開放を専用の クラスに包んでしまうのがRAIIという概念で、資源リーク回避の基本技。
414 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 20:56:19 ] >>412 push_backでイテレータは無効化される push_backの後でイテレータを拾い直すならおk
415 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 21:12:21 ] shared_ptrのコピーってポインタの十倍以上時間かかるのね これからは生ポインタ引き数でいいところは生にしよう
416 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 21:15:47 ] すいません。下記のようにやるとセグりました。どうやればいいんでしょう。 vector<Objects*>::iterator it; for(it=v_obj.begin(); it != v_obj.end(); it++){ if(ある条件){ push_back(new Objects()); } }
417 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 21:16:31 ] v_obj.push_back(new Objects())のミス
418 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 21:17:30 ] >>416 >>412 なの?
419 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 22:10:51 ] とりあえず、下記のようにして回避したんですが、もっとスマートな方法ないですかね。 vector<Objects*>::iterator it; for(it=v_obj.begin(); it != v_obj.end(); it++){ if(ある条件){ flag = true; } } if(flag){ flag = false; v_obj.push_back(new Objects()); }
420 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 22:12:32 ] >>416 別にテンポラリのvectorを作って、ループの中ではテンポラリの方に追加しておいて、 ループを抜けてから連結。 あと、激しくメモリリークの予感。
421 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 22:21:38 ] >>407 把握しました。 >>410 >>413 Test t1;の動作は理解していましたが、newはメモリ領域を確保するだけで、インスタンスは生成しないものだと思い込んでいました。 つまり、>>404 さんが示してくれた方法の場合、ヒープ領域を使用していないからdeleteはできないし不要なわけですね。 下記のように書くと、1行目と2行目で計2回インスタンスを生成していて、2行目でnewしたインスタンスが完全に無意味になる上に Testクラスにポインタを使用しているメンバ変数があった場合、そのメンバ変数に割り当てられたヒープ領域が開放されない(リーク)というおまけが付いてくると。 1:Test t1; 2:Test *t2 = new Test(); 3:t2 = &t1; shared_ptrはおもしろいですね。 メンバ変数に関してはデストラクタにdeleteを書けば良さそうですが ローカル変数に関してはこれを使っておけば安心できそうです。 ためしに近々使ってみます。 ありがとうございます。
422 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 22:23:54 ] >>416 生ポインタをコンテナに突っ込むのはやめれ、どうしてもというならshared_ptr を使うと幸せになれる
423 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 23:28:10 ] STLは糞。全部自分で管理するしくみを作った方が早い。
424 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 23:37:25 ] >>419 やりたがってることがイマイチわからないけど、そのコードから受け取れるものだけで言うなら、 ループ内でこうすればいいんじゃないの? if (ある条件) { v_obj.push_back(new Objects()); break; } 今回の君のコードからは、一つでも「ある条件」を満たすものを見つけたら もうその時点でループは用済み、という状況がうかがえるので。 そういうこと(何をやりたいか、何をやらなくていいか)をちゃんと書いて欲しいんだけどな、 質問する時は。
425 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 23:52:52 ] プログラムを簡略化してるからちょっと分かりずらいかもしれません。 ループは最初から最期まで全てのイテレータである処理をしてます。 (*it)->do_something(); 途中でbreakするわけにはいかないです。 この方法だとif(ある条件)が複数回満たされた場合に1回しかpush_backしませんが、 今回はこの方法で私の問題は解決しました。複数回できればなお嬉しいですが。
426 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 23:59:06 ] 譲れない条件を「簡略化」したら、「分かりづらい」じゃなくて、わからなくなるよ。 もう他に新事実が無いというのなら、for文の前にint count = 0;でも置いて、ループ内で if (ある条件) { ++count; } として、あとからcount個の要素を追加すればいい。
427 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 00:09:07 ] 粘着うぜ
428 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 00:15:53 ] >>415 shared_ptrのconst参照という手もあるよ。 >>421 メンバ変数もshared_ptr使っておくほうがいい。デストラクタでdeleteだと抜けがある。
429 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 01:02:22 ] >>421 リークする、と断言したのは、 1:Test t1; 2:Test *t2 = new Test(); 3:t2 = &t1; としたときに2でヒープに確保した領域をdeleteできなくなるから。
430 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 02:53:47 ] >>421 まだ何か誤解があるぽ。 > Testクラスにポインタを使用しているメンバ変数があった場合、そのメンバ変数に > 割り当てられたヒープ領域が開放されない(リーク)というおまけが付いてくると。 そうではなく、Testクラスのインスタンスがnew Test()によってヒープ領域に生成 されるが、CやC++では、ヒープに確保したメモリ領域は自分で解放する必要がある。 newで確保したならdeleteで。mallocならfreeで。new[]ならdelete[]で。 だが、そのコードでは、newでヒープに確保したメモリ領域を指すポインタはt2に まず代入されるが、t2 = &t1;の時点で上書きされるので、newした領域がどこに あるか分からなくなる。つまりdeleteできないので、普通に考えればリーク確定と いうこと。Testクラスのインスタンスそのもののメモリ領域がリークする。
431 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 07:32:21 ] 純粋仮想関数を持つ抽象クラスはインスタンス化できませんが デフォルトコンストラクタをprotectedとして宣言、定義して、インスタンス化拒否を明示するのか コンパイラが自動的に生成するのを用いるのか、どちらが妥当なんでしょうか。
432 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 07:40:35 ] >>431 なんでそんな余計なコードを書こうかなんて思うの?
433 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 10:04:21 ] >>428 shared_ptrは一般的なんですね。 レスポンスが少し気になるところですが、使っておきます。 >>429 new Test();がdelete不可なんですね。把握しました。 ※newして生成したインスタンスを格納した変数は、deleteせずに他の値を格納すると デストラクタ内で処理されているか、スマートポインタを使用していない限り必ずリークする。 >>430 昨日は少し混乱していました。 Testクラス内にメンバ変数がなくても、newした段階で最低1byteは使用するため、結局deleteできなくてリークすると。 今度こそ完全に理解しました。
434 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 10:10:52 ] >>433 大丈夫、未だ勘違いしている。 生成したインスタンスのポインタを格納しているポインタ変数に、他の値を格納してしまうと 単純に、最初のインスタンスのポインタが失われるのであってデストラクタも何も走らない。 まさに、>408だな。
435 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 10:37:19 ] なんと! デストラクタ内で適切に処理しておけば問題ないと考えていましたが、書き方によってはリークするんですね。 ヒープに確保した領域が行方不明になるような書き方してたら コンパイルエラーにしてくれればいいのにというのは甘えですか?
436 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 10:54:29 ] 1:Test t1; 2:Test *t2 = new Test(); 3:foo->bar(t2); 4:t2 = &t1; この場合leakするかどうかは 3 の内容に依る。不完全 な警告をコンパイラに実装して「警告が出てないから leakしてない」なんていう阿呆を産み出すよりは出さな い方がマシ。
437 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 11:02:31 ] 書き方によってはリークするのではない。 適切に書くことによってリークしないのだ。 -- Test * func() {return new Test();} -- void someOtherFunc() { func(); } -- これでもリークするわけだが、例えばfunc()が別のコンパイル単位にあるとしたらどうやって検出しろと?
438 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 13:07:17 ] 3行目はいったい何をしているのでしょうか? 関数のプロトタイプ宣言のように見えますが そうすると戻り値がvoidで関数の名前がInitで引数は無し?*の意味は・・・? .h.cppのどちらにもInitを実装しているような箇所は見当たらないし 3行目はどうゆう意味なのでしょうか?
439 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 13:10:32 ] 失礼しましたソースです。 //Common.h 1: struct STAGE { 2: const wchar_t* Name; 3: void (*Init)(); 4: int TopTime; 5: };
440 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 13:13:27 ] 関数ポインタです。
441 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 13:14:16 ] >>438-439 引数も戻り値もない関数へのポインタ。 わからない単語はぐぐればいいと思うよ
442 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 13:14:21 ] >>439 型がよく判らないときは、括弧に注目。この場合、Initに*がついていてそれが括弧で拘束されている。 つまり、Initはポインタ変数であることが判る。 それが指しているものは、void ()()となるので、戻り値のない、引き数もない関数となる。 要は、void func()という関数と同じ型の関数ポインタであるInitの宣言。
443 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 13:36:04 ] 少し調べてみました。 メモリ領域はコード、データ、ヒープ、スタックの4種類にわかれている。 //関数ポインタ。コード領域へのポインタ。 void (*Init)(); //普通のポインタ。データ領域へのポインタ。 int *a; //deleteしないとリークするポインタ。ヒープ領域へのポインタ。 int *a = new int(); //スタックは今のところ使い方がよくわからないので割愛。 構造体の中に関数ポインタを入れておくと、より汎用的なコーディングができる事がある。 助かりました。
444 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 13:39:29 ] >>443 ヒープに確保されないオブジェクト、つまり自動変数とかはスタックに確保されて、 スコープアウトしたらデストラクトされる。
445 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 13:58:05 ] >>444 補足ありがとうございます。 //普通の変数。スタック領域に実態がある。 int main(){ int a; Cls b; } //普通の変数。データ領域へのポインタ。 class Cls{ public: int a; TestCls b; } //これはスタック違いかな?メモリ領域のスタックの事ではなく、スタックという機能? #include <stack> template<Class T, class Container = deque<T> > class stack{};
446 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 14:01:46 ] >>445 *が付いてなければおよそポインタではない まだ何か勘違いしてない?
447 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 14:21:55 ] >>445 スタックってデータ構造もあるけど、それに近い機能をもったメモリ領域がある。 関数とかの中で、 { /*DoSomething...*/ } のように記述するとブロックとして認識されてそのブロックの中で宣言された自動変数はブロックを抜けると破棄される。 これをスコープという。ブロックは入れ子にしたりして何個でも作れる。 ポインタなどはポインタ変数は破棄されるが、指してる先をdeleteするような器用さはない。 ちなみに、以下は class Cls{ public: int a; TestCls b; }; どっちの宣言も自動変数。 sizeofで見てみるとわかると思うけど、sizeof(int)+sizeof(TestCls)の領域が確保されることになる。 C++の参照型は、 Cls& <- 一度しか初期化できない参照。 Cls* <- 何度でも初期化できる参照。名前はポインタと呼ばれる。 javaだとクラスを宣言すると無条件でC++でいうCls&の形をしたポインタが使われるみたいだ。ちなみに俺はJAVAは初心者以下だ。
448 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 14:37:27 ] 仮想関数テーブルとか考えると危険な…いや、なんでもない よく分かってないことは書かないことにしましょうか
449 名前:447 mailto:sage [2009/10/30(金) 14:47:30 ] >>448 vtableは使ってないから説明してない。 仮想関数のオーバーライドの説明だけど、 C++の上書きオーバーライド(virtual function)は、大雑把に言って関数ポインタを上書きすることで実現している。 そのためにはクラスのメモリのどこかに関数ポインタのリストを持つためのポインタを持つことになる。 基本的にこれはメモリを操作してかきかえる類ではないのであることを知っていればいい。 で、仮想関数を持ったクラスをsizeofをすると関数ポインタのリストのポインタ変数のサイズ分増分して返ってくる。
450 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 15:06:07 ] >>446 ×//普通の変数。データ領域へのポインタ。 ○//普通の変数。スタック領域に実態がある。 なんかもう滅茶苦茶ですね。 書き間違いと勘違いといろいろまざtt・・・ >>447 #include なんちゃら int gInt; //データ領域に実態が格納されているグローバル変数(非自動変数) TestCls gCls; //同上 class Cls{ public: int a; //スタック領域に格納されている自動変数 TestCls b; //同上 }; int main(){ int a; TestCls t; //スタック領域に格納されている自動変数 } 今度こそOKでしょうか? >>448 >>449 初めて目にした単語なので、wiki見てみましたがイミフ。 基底クラスAを継承したサブクラスB,Cがあり Aで仮想関数speakを宣言し、B,Cクラスでそれぞれ実装した場合、次の関数の呼び出しはどうなるか? ClsB b; ClsA *a = &b; a->speak(); どう考えてもBで実装したspeakが呼ばれます。vtableの入る余地がありません。 ちょっと試行錯誤してきます。
451 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 15:29:09 ] 1.ClsA *aはポインタ型なんだから、ClsAの継承クラスのインスタンスならどれでも受け入れられる。 2.受け入れるオブジェクトの型は、ユーザーの入力などにより動的(実行時)に変化する。 以上より仮想関数テーブルが必要になる。 450のように、静的(コンパイル時)に型が限定できる場合ばかりではないということ。
452 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 15:29:31 ] >>450 基本的にグローバル変数も自動変数というルールに違いはない。 それは、グローバルスコープに宣言されているという前提になる。 あと、ちょっと妙な書き方をしてしまったので訂正するが、 class Cls{ public: int a; //スタック領域に格納されている自動変数 TestCls b; //同上 }; 上のクラスをnewしたら、自動変数とされる領域もヒープに確保される。でも動作は自動変数と変わらない。 deleteした瞬間がスコープ終了の瞬間。 あと、オーバーライドの話。 C++のオーバーライドはvirtualをつけなかったら、上書きされない。よって、vtableも生成されない。 つまり、基本的には、そのクラスで宣言されたそのメンバ関数が呼ばれる。 virtualをつけてオーバーライドされる前提のメンバ関数は継承先で上書きすることができる。 virtualの上書きされた関数は、基底でも上書きされた関数を呼ぶ。 もちろんインスタンスは実装したクラスのインスタンスじゃないといけないけども。
453 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 15:43:11 ] ちょっとした違和感を感じたんだが、 >>450 の言うデータ領域って、たとえばimmutableな文字列定数とかを格納するところかな?? static constの変数とか。
454 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 15:59:33 ] 何かもう、ネイティブコードでどう実装されてるかから説明した方が早い気がしてきた
455 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 16:25:02 ] >>451 ttp://codepad.org/Pldw34mI 1と入力するとsub1が表示され、1以外を入力するとsub2が表示されます。 何も問題ありません。頭が爆破寸前です。 >>452 >上のクラスをnewしたら、自動変数とされる領域もヒープに確保される。 おkです。 >でも動作は自動変数と変わらない。 >deleteした瞬間がスコープ終了の瞬間。 自動変数の定義は、「関数内で宣言された記憶クラス指定子の付かない変数」ですよね? deleteさえしっかりやれば、newしたものも自動変数と同じ振る舞いをすると。 >>453 >>450 のソースのコメントは間違い・・・? 下記2種「以外」の変数が格納される領域がデータ領域? ・グローバル変数 ・自動変数
456 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 17:10:43 ] >>455 C++におけるメジャーなメモリ領域は2つ。 一つはスタックと呼ばれる領域。一つは、ヒープと呼ばれる領域。 スタックは宣言したときに確保されてスコープが終了したら破棄されることを約束された領域。 ヒープはメモリのプールで必要なときに確保して不要になったらユーザの責任で開放する。資源は有効に。 で、コード領域やデータ領域というのはコンパイラやOSの最適化によって発生した領域。 たぶん、データ領域は何度も参照されるような定数データを効率よく回すための機構で基本的に書き込み禁止。 で、たぶん、コード領域はプログラムコード自身をOSがロードした領域。 なので、後の2つはC++の仕様外だと思う。
457 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 18:40:54 ] >>456 静的記憶期間(static付きやグローバル変数など)のオブジェクトの置き場なのだから、 データ領域はスタック・ヒープと同列に扱おうよ。 規格書でも(言葉は違うけど)その3つの概念は出てくることだし。
458 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 19:24:41 ] コンパイル時には、ClsSub1になるのかClsSub2になるのかわかっていない。 →このままでは、ClsSuper::test(), ClsSub1::test(), ClsSub2::test()のどれとしてコンパイルすればいいのかわからない。 このコードで言うと、sub1, sub2 superのどれを表示していいかわからない。 ここまでは大丈夫? 次に、ClsSuperの隠しメンバ変数にpTestFunctionという関数ポインタを追加して、 実行時、インスタンスが生成時にその関数ポインタへ使用すべきメンバ関数を代入するようにする。 ClsSuper *s; には使用すべき関数ポインタが含まれているので、 コンパイル時に s->test(); という文を、関数ポインタからの呼び出しに翻訳する。 実行時に、sがどの型をさしていようと適切な関数ポインタが指定されるので、問題なく実行できる。 > 1と入力するとsub1が表示され、1以外を入力するとsub2が表示されます。 というのは、仮想関数テーブル(=関数ポインタのようなもの)が仕事をしてるから。 とりあえずコメントにも補足書いたけど、以上が仮想関数テーブルが必要な理由。 codepad.org/uuPlC3eO
459 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 20:26:13 ] >>456 >>457 も言ってるけど、スタックとヒープと静的の三つとした方が。 静的記憶は普通に読み書き可能なことが多いんじゃないかな、x86では。dsセレクタで アクセスされるようなセグメントに配置するのが一般的な気がする。 リードオンリーの定数はむしろ、コンパイル時点で埋め込んじゃう気がするし。
460 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 20:47:25 ] スタックもヒープも物理的には同じだぞ。 コンパイル時に固定サイズの領域を割り当てるのがスタック。 スタック不足になるのは、メモリが足らないからではなく 予測以上に初期の固定メモリを使い切ったため。 物理的には、スタックもヒープも違いはないので、 多くメモリ確保するなら動的=ヒープがいい。
461 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 21:00:19 ] >>456 >>457 >>459 >>460 今の私の認識と、説明していただいたメモリ領域の説明がだいたい一致するので メモリ領域に関しては大丈夫そうです。 >>460 >多くメモリ確保するなら動的=ヒープがいい。 私がはじめに学んだ言語ではそのあたりを気にしながらコーディングしていましたが c++においてはまったく意識してませんでした。 メモリをいっぱい使うような処理をする場合には気をつけてみます。 >>458 40行目で正しく関数が呼べてるのは仮想関数テーブルがあるからなんですね。 コーディングしている分には見えないものですが、内部的には説明してくださったような動作になっていると。 今日1日でc++に対する理解度がだいぶ深まった気がします。
462 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 21:05:38 ] aa
463 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 21:08:23 ] でもヒープ確保には、OSとのやりとりがあって、生成に時間食うがな。 スタックは、はじめに確保した領域を使い回すだけだからOSとのやりとりはなく 高速。
464 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 21:11:40 ] 動作速度に関しては、 スタック ヒープに違いはないが 生成と破棄に関しては違いが出るってこと。 長いこと(10秒以上とか)保持するなら、 生成コストは無視できるから 安定性のためヒープを使う方が良いな。
465 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 22:07:18 ] 待て待て、スタックとヒープは実装原理が全く違うがな。適当言うんじゃない。 一般的なスタックは、pushするかスタックポインタを移動させることで積み上げて、 破棄する時はスタックポインタの移動だけで終わるから、ヒープに比べたら圧倒的に 確保も解放も高速だぞ。
466 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 22:08:28 ] 確保と解放は速度差があるが、確保されたメモリを使う分には同じ速度だな。
467 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 22:26:53 ] >>465 確保方法に違いはあっても、どちらも同一の(実)メモリつかうんだよ。 OSに問い合わせるか、C言語が管理している領域に問い合わせるかだけ。 スタックでさえ仮想メモリに移動することもある。 OSや他のアプリからみれば特殊な物ではない。
468 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 23:41:54 ] とりあえず確保解放の速度が圧倒的に違うのは確実だけどな、スタックとヒープじゃ。 >>466 がほとんどの環境で正解。
469 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 23:44:38 ] 圧倒的に違うといっても総実行時間の何%だよ 以下ループ
470 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 01:50:36 ] ボトルネックに突っ込んだら恐ろしく違うだろうな
471 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 03:11:39 ] まぁ環境によっていろいろあるってことでFA
472 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 03:48:03 ] dllを作っているのですが デバッグでは作成できて、リリースしてビルドすると ライブラリ ***testdll.exp を作成中 LINK : fatal error LNK1561: エントリー ポイントを定義しなければなりません。 ビルドログは "***" に保存されました。 testdll - エラー 1、警告 0 と表示されてできません どうすればできるのでしょうか・・・・・
473 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 03:52:30 ] >>472 「エントリーポイントを定義しなければなりません」 ↓ エントリーポイントを定義すればできる これぐらいの推測ができないようじゃ、前途多難だな。
474 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 11:53:20 ] enumとかstatic constの定数は外のクラスに見せないならクラススコープでprivateで定義するのが良いんですよね?
475 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 12:31:50 ] コンテナのイテレータから、渡されたコンテナの要素数を求めることはできますか? template<class Iterator> size_t Size(Iterator it) { return ?; } int main() { std::vector<int> lhs; lhs.push_back(1); lhs.push_back(2); std::vector<int>::iterator ite; ite = lhs.begin(); int n = Size(ite); // こんな感じでコンテナの要素数を求めたいのですが }
476 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 12:34:41 ] vector::size()では何か不都合でもあるの?
477 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 12:42:59 ] >>475 です vector::size() をこのように使っているのですが これでは、イテレータを渡しても、当然のことですがエラーになってしまいます、 なんとかイテレータを渡して、そのコンテナのサイズがわからないものかと思案しています。 template <class Container> inline size_t Size(const Container& c) { return c.size(); }
478 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 12:55:04 ] 要素へのポインタを所有しているコンテナを特定する手段があるなら可能
479 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 13:02:22 ] >>470 ボトルネックの個所で スタックだろうがヒープだろうがメモリの確保解放するコード書くのは論外だろう
480 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 13:09:48 ] >>479 秒間一万回程度の半端なボトルネックだと、スタックかヒープかで致命的な事態に なるだろうな。 まぁ、違いを知った上で、大差無いと判断したところで使うのは最初から問題無い。 「違わない」と断言するのは激しく問題があるってだけ。カーネルに落ちる場合は スタックの数万倍も重いことがある訳で。
481 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 13:10:09 ] >>478 thx です 関数オブジェクトを作っていて、引数が多くなってしまい なんとか、減らせないものだろうかと思い質問したしだいでした 要素へのポインタを所持しているコンテナを引き渡すのなら、 要素数を引き渡すだけのことなので、同じくらいのコストがかかりそうで あききらめますが、要素へのポインタを所持しているコンテナを引き渡して 要素数を求める方法へ関心があります、単純な実装例をご教示願えませんか。
482 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 13:29:21 ] c.size()
483 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 13:45:50 ] >>477 イテレータのペア(開始と終端)を取る関数オブジェクトなら std::distance(it1, it2) で [it1-it2)間の要素数が求められるよ。
484 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 14:20:44 ] >>475 ,477,481 ひとつのイテレータからコンテナの要素数を求める一般的な方法はないよ。 実装依存の機能でそういうのがあるか、自分で実装すれば可能。 beginとendがあるなら>>483 のでいける。
485 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 18:59:20 ] >>484 ありがとう >実装依存の機能でそういうのがあるか、自分で実装すれば可能。 もし仮に実装するなら、どんな感じになるのでしょうか? まずは、イテレータのアドレスを取得しなければならないのはわかるのですが それ以降の展開が想像できません、向学のために概略だけでも教えてもらえないでしょうか。
486 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 19:11:13 ] >>485 MinGW だとイテレータはコンテナのアドレスを持ってるようだ
487 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 20:54:21 ] そもそもイテレータ渡ししてるのに本当に要素数が必要なのかから考えるべきな気がする。
488 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 21:51:29 ] >>485 元のイテレータの派生クラスかラッパークラスを作って、そいつに要素数か親コンテナのポインタを持たせる。 しかし、親コンテナの要素数が必要な処理ってどんなだ? コードをさらしてみる気はないか?
489 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 21:56:41 ] 技巧する必要なし 元のをを渡せよ。
490 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 22:09:55 ] 引き数へらしたいならレンジイテレータでもつかってコンテナまるごと渡せよ
491 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 21:07:20 ] 演算子のオーバーライドって一般企業でも使ってますか? パッと見どうゆう動作をするのかわからないから、危険な香りがするのですが。 例えば、タスクシステムを使っていて、とあるクラスをnewするとそのクラスをタスクに追加したりするような仕組みの場合 一見メモリリークするコードに見えます。
492 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 21:13:44 ] >>491 基本的にそういうことはドキュメントに書いておくべきことじゃないかなぁ。 読まない人もいるみたいだけどね。読みやすいドキュメントって言うのもむずかしいけど。
493 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 21:13:49 ] >>491 何を使っても酷いことになる人はどこにでもいるよ
494 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 21:28:12 ] >>491 そんな事言ったらoperator+をオーバーロードしてマイナスの動作を させるへそ曲がりな事だって出来るぞ 仕様書でちゃんと最初に決めとけ
495 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 21:46:43 ] >>491 危険だよ。だから是非使うべきだと感じないなら使うものではない。ただ、例えば、 class に + or - があればすごく楽な場合があるでしょ。operator overloading して a+b+c と書くのと a.plus(b).plus(c) とか書いたり してわかりにくくなる(そしてミスしやすくなる)のとのどちらが良いか。 どう使うかによる。グループで仕事してるなら合意が必要。たとえば、一応 ttp://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Operator_Overloading#Operator_Overloading
496 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 22:15:04 ] >>491 基本的には使わないだろう。企業に限らず。 でも、例えば多倍長整数クラスとか、有理数クラスとか、ベクトルクラスとかを 作るなら、operator+を定義しても恐らく誰も間違わない。そういう場合は使う 方が楽という判断も十分有力だし、それでも使わないという判断もやはり有力。
497 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 22:17:08 ] まぁ、暗黙の変換なんかと同じだな。 無闇やたらと使うのは糞設計だが、完全排除すれば良設計というものでもない。
498 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 22:28:05 ] 微妙なら()つけろよ。簡単のために公開しない関数内部で使うなら別に良いだろ。
499 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 23:31:40 ] >>497 俺は argument 一つの constructor はやっぱり explicit 付けてる。 operator overloading の方はたまに使う時がある。
500 名前:デフォルトの名無しさん mailto:sage [2009/11/03(火) 03:04:26 ] スマポなんかは暗黙の変換に対応しないと微妙
501 名前:デフォルトの名無しさん mailto:sage [2009/11/03(火) 06:28:54 ] >>491 × オーバーライド ○ オーバーロード あと、タスクシステム死ね。 > とあるクラスをnewするとそのクラスをタスクに追加したりするような仕組みの場合 > 一見メモリリークするコードに見えます。 具体的なデメリットがわかってるのに、なんでそのうえで一般論を持ち出す必要があるの?
502 名前:デフォルトの名無しさん mailto:sage [2009/11/03(火) 14:46:36 ] すいません。下記のようなことがやりたいのですが、 ”\debug.cpp(13) : error C2059: 構文エラー : ')'” と表示されコンパイルが通りません。どうしたらいいですか。 void Debug::create_debug_message(...) { char tmp_str[100]; sprintf(tmp_str, __VA_ARGS__); // line: 13 }
503 名前:デフォルトの名無しさん mailto:sage [2009/11/03(火) 14:50:37 ] >>502 void Debug::create_debug_message(const char *format, ...) { char tmp_str[100]; va_list ap; va_start(ap, format); vsprintf(tmp_str, format, ap); }
504 名前:デフォルトの名無しさん mailto:sage [2009/11/03(火) 14:58:30 ] できました。ありがとうございました。
505 名前:デフォルトの名無しさん mailto:sage [2009/11/03(火) 15:54:29 ] そういや可変長引数長い事使ってないなあ リハビリしとかなきゃ
506 名前:491 mailto:sage [2009/11/03(火) 18:00:50 ] >>492-497 多倍長整数クラスの+のように、直感的にわかるような動作をするものなら演算子のオーバーロードをしても良いが 基本的に多用するものではないということですね。 >>501 >×オーバーライド 間違いを確認しました。 >具体的なデメリットがわかってるのに、なんでそのうえで一般論を持ち出す必要があるの? デメリットがあっても、それを打ち消すようなコーディングの仕方や デメリットを凌駕するメリットがあれば、演算子のオーバーロードを積極的に使っていこうと考えていたからです。 私はC++を勉強しはじめてまだ日が浅いので、私の知らない何かがあるのかもしれないと思い、質問させてもらいました。 一般的な演算子のオーバーロードに対する考えが聞けて、とてもためになりました。 ありがとうございます。
507 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 12:21:15 ] >>506 業種によっても違うんじゃないかな。 私のところは画像処理や数値計算関係なので座標の足し算とかベクタの掛け算なんかが 頻発するので演算子オーバーロードはあるとないとじゃ大違いだから。
508 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 16:41:27 ] ベクトルの掛け算も演算子オーバーロードしちゃうのか… 内積にすんのかな
509 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 16:48:04 ] スカラ倍のことじゃないの
510 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 17:07:21 ] 内積、スカラ倍両方オーバーロードするのもありだな。 いずれにせよ、ベクトルや行列使った数値計算とかは オーバーロードしないとコードが読めなくなるからリスクとの トレードオフとして悪くないと思う。
511 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 17:18:02 ] インラインアセンブラと組み合わせれば演算子でSIMDも可能 って考えるとなんか夢が広がるような気がするよね 実際には関数呼び出しだって同じなんだが、表記的に 高水準(抽象的)・低水準(具体的)の混在具合が脳汁出そう
512 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 17:59:50 ] ベクタ×ベクタは演算ライブラリによっては内積だけど、 演算ライブラリによっては敢えて用意していないね。 それでもスカラ積があるだけでも随分違うけど。
513 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 21:19:06 ] 「絶対に内積だろ」とは言い切れないし、スカラ積だけ対応するのが個人的には好み だけど、内積でも別に文句言うほどじゃないかな
514 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 21:55:01 ] スカラ積って内積じゃないの
515 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 21:59:47 ] iostreamやBoostに見られるような「Cの文脈からかけ離れた演算子オーバーロード」 は、実際使ってみると割と平気だったりするんだよな。 ただ、見慣れない問題に直面する可能性も高いから、やっぱりお仕事だと微妙かな。 boost::formatとか激しく便利ではあるんだけど。
516 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 22:57:49 ] >>514 数Bやり直せw
517 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 23:06:14 ] >>516 おまえこそやり直せ
518 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 23:14:19 ] 小学生ktkr
519 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 03:19:55 ] スカラー積=内積 ベクトル積=外積
520 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 08:51:58 ] >>503 va_endわすれてるぞ
521 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 09:18:30 ] スカラー積ってスカラ倍のことじゃないの?
522 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 09:24:31 ] もうその話題は終わり
523 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 09:48:19 ] namespace Hello { class A; }; namespace World { class B; }; ヘッダーファイルに上記のように書いたところ、 class Bの所属がなぜかHello::World::Bとして扱われてしまい、 コンパイルエラーになります。これはコンパイラのバグでしょうか? 環境はwinXP x86 VC++ 2008Expressを使ってます。
524 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 10:01:37 ] どうせ打ち間違い 523自体は正しい
525 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 10:03:15 ] ていうかエラーメッセージ書けって
526 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:07:06 ] もう少し状況を詳しく書いてみます "helloworld.h" namespace Hello { --class A; } namespace World { --class Hoge; --namespace Button --{ ----enum Value { A, B, C }; --} }; "hoge.h" #include "helloworld.h" namespace World { --class Hoge --{ --public: ----Button::Value m_value; --} }; "error messeage" C3083: 'World': '::' の左側のシンボルには、型を指定しなければなりません C2460: 'Hello::World::Value::m_value' : 宣言されている 'Hello::World::Value' を使用しています。
527 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:10:32 ] >>526 namespace Helloが閉じていない。 # まぁ、想定の範囲内だな。
528 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:11:50 ] Hello:: まで書くとvisual studio のインテリセンスがWorldや ヘッダーに書いた他のnamespaceを全部含んでしまっているように表示します。 World::やその他のネームスペースからはHelloを参照することはありません。
529 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:14:22 ] ;が抜けているのに気づけない間抜けであったか。
530 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:14:30 ] 本当だ。すいません小さなミスでした。
531 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:32:52 ] VCなんですけど floatとdoubleはどっちが速いですか?
532 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:39:13 ] >>531 一概には言えませんが、doubleで組んで速度に不満があったら両方実測して比較すればよいでしょう。
533 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:43:23 ] floatが速いよ 昔は、doubleに変換されるという説もあったが、いまは直に計算する。
534 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:45:13 ] 特に配列に格納すると、メモリ呼び出しが半分のサイズですむから 計算だけではなく、メモリサイズと呼び出し時間が短縮できる。
535 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:52:00 ] フロートがSSEで二倍速い
536 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 12:10:08 ] namespaceって;必要だっけ?
537 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 13:15:38 ] 必要じゃないことはないですよ
538 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 16:20:32 ] floatにしてみます。
539 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 16:43:18 ] floatは有効桁数がIEEE754では6桁しかないよ だから用途が限られる 画面座標とか
540 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 17:46:27 ] 配列のインデックスは符号無しですか?
541 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 18:05:17 ] 厳密に言えば、いいえ
542 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 18:58:15 ] ポインタの計算だからマイナスもある
543 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 19:14:31 ] まず配列のインデックスの定義をだな
544 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 20:29:16 ] namespace は ; いらないよね?? class は ; いるけどさ。 ていうか namespace {} に ; つけないで普通に使っているんだが…
545 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 20:35:52 ] クラス定義は文だから;が必要で名前空間はスコープだからいらない。たぶん
546 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 20:46:17 ] 確かポインタ間の距離はptrdiff_t型で符号あり整数じゃね?
547 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 21:08:49 ] struct foo { int bar; } buzz; class foo { int bar; } buzz; namespace foo { int bar; } buzz; // ← これだけ明らかにおかしく見えれば大丈夫
548 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 10:11:30 ] >526がセミコロンが抜けているのは事実だが、>527は間違い。 >534、>535は正しいが、速度よりも>539の問題の方が通常は問題になるので、doubleを使っておくのが無難。 ポインタ演算については>542、>546の通りだが、>543の言うように「インデックス」が何を指しているかが問題。
549 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 13:20:14 ] C/C++でZipファイルの追記したいのですがいいライブラリありますか。 DLL使うと、中間ファイルを生成してから追記するので遅いです。 100Mのzipファイルならそれをopenして追記したいです。
550 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 13:31:39 ] tarならできるだろうけどzipはむりじゃね
551 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 13:33:27 ] zlibは圧縮は出来るけど、書庫のフォーマットには対応してないですよね?
552 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 13:36:35 ] >>550 このwebサイト収集するやつは、zip追記してます。 でもC言語でやってないです。 www.unixuser.org/~euske/python/webstemmer/index-j.html
553 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 14:01:44 ] >>550 外人がいいやつ作ってくれました。 これで追記出来ました。 www.wischik.com/lu/programmer/zip_utils.html
554 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 18:19:57 ] >>548 > doubleを使っておくのが無難。 それは微妙。どっちが向いてるのか考えるべき。ちょっと考えれば大体正解が選べるし。 例えば、APIがfloatを要求してるような場合はfloatが無難。 floatは精度に注意、floatとdoubleを無駄に混在させるのはアホ、SSEでは圧倒的に速度 が違う、SSE使わないならほんの僅かにfloatが速い、くらいであとは自己判断かな。
555 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 20:10:20 ] 混在を避けるのは鉄則。doubleの演算速度よりも、float⇔doubleの変換の方がよっぽど遅い。
556 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 20:12:50 ] >>555 え?
557 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 20:14:14 ] 下のようにvectorの入った構造体があります。 typedef struct { std::vector<int> foo; std::vector<float> bar; } HOGE; これを値渡しすると、各vectorのコピーコンストラクタはちゃんと呼ばれるんでしょうか。
558 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 20:17:36 ] >>556 それも環境次第だとは思うけど、少なくとも整数の符号拡張みたいに単純にはいかない。 フォーマットの変換が必要だから。 x86のFPUだと相当なコストがかかるけど、SSEなんかだとどうかは知らない。
559 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 20:24:57 ] >>557 ヒント : C++では基本的にclass と struct は同等の扱い デフォルトのprivateとpublicが違うだけ
560 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 21:13:15 ] >557 ヒントより短い答え:呼ばれます。
561 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 22:03:45 ] そんな巨大になりそうなもの値渡しして欲しくないな
562 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 22:24:42 ] 大丈夫 俺のちんこよりは小さいから
563 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 22:50:31 ] >>553 よく読めてないけど、オンメモリで展開、追加、圧縮をやってるんじゃないの?
564 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 23:55:53 ] >>561 新人「大丈夫ですよ先輩。sizeofで見たらたった80バイトです」
565 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 00:00:20 ] ああそうだ、俺のコンパイラは構造体に巨大な配列を入れて 値渡しすると馬鹿みたいにpushの荒らしになる rep movsが使えないのはpushが逆順になるからだろうな それなら簡単なループ組んで転送すればいいと思うのに pushを配列数分吐くもんだからexeが巨大になって馬鹿みたい
566 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 00:00:29 ] >>563 追記は新規に作ったファイルだけだった 既存ファイルには追記できなかった 追加しようとしたらデータ初期化されたよ
567 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 00:09:08 ] zipフォーマットここに書いてあるから追記自分でやってみるか www.tnksoft.com/reading/zipfile/arczip.php www.tnksoft.com/reading/zipfile/nonarc2.php
568 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 00:17:40 ] もう一度いうけど、tarならできるだろうけどzipは無理だと思う。 無圧縮zipならできるかな
569 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 00:20:34 ] 100個のファイルを圧縮したzipを用意して、それを展開して、一つファイルを増やして、 圧縮して、バイナリ比較して、「追記」が実現可能かどうか見てみたら。 無圧縮でもそれやってみたら。
570 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 00:30:05 ] 駄目な理由はなんだ> 絶対出来るはず
571 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 01:25:11 ] rep movsとか最近のコンパイラは間違っても使わないような
572 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 01:39:47 ] サイズ重視のコードなら使う
573 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 02:11:52 ] 俺のコンパイラは断りもなくmemcpy呼んでるな。構造体の初期化には勝手にmemset使うし。
574 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 02:18:32 ] >>573 それで何か問題でも?
575 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 02:23:41 ] >>571 変数の初期化に使われているよ 特に配列だと間違いなく出てくる
576 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 02:34:11 ] そもそも構造体の値渡しが必要な状況ってどんなの? ポインタや参照が使えない状況ってのが思い浮かばない。
577 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 02:55:20 ] 逆に考えるんだ。ポインタでは困る場面なんだよ。 それが必要な状況?それは↓
578 名前:デフォルトの名無しさん [2009/11/07(土) 03:36:48 ] ぬるぽ
579 名前:デフォルトの名無しさん [2009/11/07(土) 06:46:06 ] 再帰させるときなんかたまに使うけどね。
580 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 07:46:51 ] RECT rc = { 0 }; とかってありなの? VCだと中の変数ゼロになるんだけど
581 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 08:04:27 ] そうだよ
582 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 08:11:19 ] zip64の追記つくってくれ
583 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 08:15:20 ] 後半の情報フォーマット部分を追記データで 書き換えれば理論的には可能なはずなんだ。 でも正しいセットの仕方が判らない。
584 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 11:04:21 ] zipの仕様は公開されてるからそれに従って書けばいいと思うよ www.pkware.com/documents/casestudies/APPNOTE.TXT
585 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 11:15:53 ] ファイルを個別に zip 圧縮してから tar でまとめるとか…
586 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 13:03:04 ] つか 追記くらいライブラリないのかよ
587 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 13:18:34 ] zipの構造はおおまかに ファイルヘッダ 圧縮データ ファイルヘッダ 圧縮データ .... ファイルヘッダ 圧縮データ アーカイブインデックス(>>583 のいう情報フォーマット部分) てなってるから最後の圧縮データとアーカイブインデックスの間に 追記のファイルヘッダと圧縮データを入れて アーカイブインデックスにも追加できればいける 7zとかcabなんかのソリッド圧縮形式だと LZ77の辞書とエントロピー圧縮のコンテキストが必要だから オンメモリでもいいから一度展開作業をしないと追記できない ちなみにJavaScriptで無圧縮zip作るひとがいるくらいだから 圧縮をzlibですればzipのフォーマット自体はそれほど難しくない
588 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 13:39:27 ] 作ってクレオ
589 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 14:08:45 ] パイロンだと、直書き出来る。 でも巨大ファイル(個数が100万とか)に追記すると解析に時間かかる。 パイロンのzip64の追記のソースをC++に書き換えられる人いますか。 パイロンの例 import zipfile z = zipfile.ZipFile("test.zip", "a", zipfile.ZIP_DEFLATED, True ) z.write("log_data.txt") z.close()
590 名前:589 mailto:sage [2009/11/07(土) 14:13:08 ] 実際に400M、50万ファイルのZIPファイルで実験したから間違いない。 コピーしたり展開したら時間かかるが、追記はコピーより速くできた。
591 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 14:49:15 ] c言語の話題かぁ?
592 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 16:25:07 ] struct Bar { Bar(): x(m_x), m_x() { } Foo &x; private: Foo m_x; }; 初期化子の実行順序は、初期化子の順序ではなくて変数宣言の順序だと記憶していますが、 (例のコードではどちらにせよxが先だと思います。)上のようなコードを書くと、xの初期化から 始まって何物でもないm_xを参照してしまうはずなのにVisual C++のコンパイラは警告すら発し ません。 このようなコードは避けるべきということは言うまでもないですが、コンパイラがまったく順序に 関知しないというのはいかがなものでしょうか、と。
593 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 16:32:20 ] >>591 Zipは追記できないという説に対して ZipもZip64も追記できたと言うこと
594 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 17:13:59 ] >>592 嫌だったらC++使うなカス
595 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 17:14:59 ] VCで複数のソースファイルがある場合、プリプロセッサの処理順てどこで定義されているの? 例えば aaa.h, bbb.h, ccc.h の3つが互いにインクルードしている場合、 全体で使用できるためにはどのファイルで定義すればいいのかわからん
596 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 17:21:08 ] #includeした順に決まってるだろ
597 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 17:21:08 ] 何を言いたいのかわからないけど、 #includeはそこにテキストがそのまま展開される。 #include "aaa.h" #include "bbb.h" #include "ccc.h" なら aaa.h が真っ先に展開される。 しかし、非ローカルなスタティック変数の初期化順とかいう話になるのなら それはそれは難しいことに。 違ったかな。ほほほ。
598 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 17:30:31 ] 結局、「暗黙の初期化順に依存するな」ってことね。
599 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 18:04:33 ] #define #undef みたいにusing namespaceを無かったことにできないもんでしょうか
600 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 18:08:02 ] 逆に、using namespace を使うところだけスコープを切ればいい。 { using namespace boost::lambda; // ここでbindとか_1とか使う } // ここでは using namespace は無効
601 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 18:10:36 ] みんなはusing namespace std;ってグローバルにおいちゃう派?おいちゃだめ派?
602 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 18:11:45 ] Google Coding Standardsではらめってなってた。
603 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 18:12:27 ] チーム全員がstd名前空間の全内容を把握しているなら グローバルでもいいんじゃないですかね。
604 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 18:34:43 ] 同一プロジェクトでstd::stringとhoge::stringが混在したらそっちのほうがいやじゃない? だからまとめて共通ヘッダに入れてグローバルusingしてる
605 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 18:37:12 ] いちいちstd::stringとかhoge::stringと書けばいいじゃない。
606 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 18:43:32 ] >>605 結構めんどくさくね?
607 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 19:01:18 ] WinAPI使ってるともっと長くてどうしようもない名前がわらわら出てくるから あんまり気にしたことないなぁ。って言うか末尾にSEXついてるの多すぎ。 マイクロソフトの技術者はどんだけ欲求不満なのか、と。
608 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 19:01:19 ] 入力補完で切るエディタなら std::と打ったほうが楽
609 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 19:06:03 ] >>607 sexわろたw 気にしたことなかったけど確かにそうだな
610 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 19:16:11 ] >>576 インライン展開を期待するときなんか、あえて構造体の値戻しを使ったりする。
611 名前:デフォルトの名無しさん [2009/11/07(土) 19:41:39 ] WIN32APIのSendMessageを使用する時、引数のwparamを文字列で渡す方法ってある?WinXPが環境です
612 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 19:43:12 ] とりあえず、グローバル変数の初期化順序に関しては、チューリングマシンの停止問題 みたいに定義不可能な面があるから、依存するな、とかEffectiveC++に書いてあった ような気がしなくもない
613 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 19:52:02 ] そこでシングルトンの登場ですよ。
614 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 20:01:16 ] シングルトンは俺的にはもうアンチパターンだな Google的に、コンストラクタでは単純な初期化にとどめて、複雑な初期化はInit()で やれ、というコーディングを採用してれば、初期化順序で悩むことも無い気がする
615 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 20:17:49 ] 単豚
616 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 21:00:39 ] >>614 コンストラクタから初期化を追い出す必要は無いよ。 Init() 呼ぶくらいならグローバルなポインタに new すればいいじゃん。
617 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 22:58:31 ] ゼロオーバーヘッド的にはグローバルなポインタにnewするくらいならInit()呼ぶなぁ
618 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 23:26:56 ] operator newのオーバーロード(配置ではなくて)なんですけどグローバルにするのかstaticメンバにするのはどっちがいいんでしょうか?
619 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 23:31:20 ] 一緒。staticメンバは単にクラスのスコープの中に入っちゃうだけ。
620 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 23:36:58 ] >>618 追加の引数が無い奴はグローバルにすると全体に影響が出るから気をつけてな。
621 名前:デフォルトの名無しさん mailto:sage [2009/11/08(日) 00:09:48 ] ありがとうございます グローバルだと目的のクラス以外でもオーバーロードされてしまう staticメンバだと目的のクラスだけオーバーロードされる ということでしょうか。基本的にはstaticメンバにしたほうがよさそうですね
622 名前:デフォルトの名無しさん mailto:sage [2009/11/08(日) 00:12:34 ] >>621 影響範囲については、だいたいそういうこと。 細かい話をすると、クラスの奴は派生クラスでも使われる。 あと、追加の引数が無い奴をグローバルに置くのはオーバーロードじゃなくて置き換え、な。
623 名前:デフォルトの名無しさん mailto:sage [2009/11/08(日) 15:27:46 ] 基底クラスのポインタから派生クラスのポインタへのキャストって dynamic_castは遅いけど変換不能な場合NULLを返す static_castは早いけど変換不能でも知らせてくれない これ以外の違いってなんかある?
624 名前:デフォルトの名無しさん mailto:sage [2009/11/08(日) 15:34:01 ] その基底クラスが仮想関数を持たない場合、dynamic_castは使用できない その派生クラスがその基底クラスを仮想継承している場合、static_castは使用できない (両方に当てはまる場合、どちらも使用できない)
625 名前:デフォルトの名無しさん mailto:sage [2009/11/08(日) 19:45:51 ] >その基底クラスが仮想関数を持たない場合、dynamic_castは使用できない マジすか初めて知った 確かにできてもあんまり意味はないけど
626 名前:デフォルトの名無しさん mailto:sage [2009/11/08(日) 20:18:33 ] キャストしない暗黙変換が一番使いやすい。とか本末転倒なこと言ってみる。 HogeBase* hoge; Hoge2 *p = new Hoge2; hoge = p;//基底があってなかったらコンパイルエラー吐く。
627 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 01:46:58 ] dynamic_castが必要になるのは糞設計に仕方なく対応する時だけ
628 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 01:56:39 ] クロスキャストには必須だろ
629 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 02:49:46 ] クロスキャストしたい時点で糞設計になってるんじゃ?
630 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 03:04:02 ] >>629 違う クラスが複雑になるとクロスキャストしたい局面はよく現れる
631 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 03:04:46 ] ×クラスが複雑になると ○継承関係が複雑になると あ、継承関係が糞設計なんだろって突っ込みは無しな そういう事を言い出すとキリがなくなってしまうんで
632 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 03:24:18 ] そうは言っても、継承関係が糞設計なんだろ?w
633 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 03:49:06 ] >>632 ほうら来た だからそういう突っ込みは無し 人間そこまで完全な奴はいない 特にある程度プロジェクトが進んでしまっていると 今更設計を変えられない事も多い
634 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 03:55:13 ] 配られたカードがどんな悲惨でも それで何とか勝負するしかないって事はあるだろう、仕事なら。
635 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 04:06:19 ] 結局>>627 で全て終結していたわけか
636 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 04:06:54 ] 最初から「仕方なく対応する時」って書かれてるんだから、それは分かった上でだろう
637 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 04:14:02 ] 少なくともC++では、dynamic_castを使う必要が出てきた時点でほぼ糞設計。 糞設計をしてしまうことはあるし、気付いた時には引き返せないこともあるから、 使う時は使うべき。設計は変えられないが他の方法でどうにかしよう、というのは 最悪だから。 でも、そういう事態になったなら設計が糞だったんだ、という認識はすべき。
638 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 04:50:41 ] >>637 それは当たり前だろう そんな事はわざわざ言わなくても誰でもわかっている
639 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 04:58:39 ] つーかそれ以上の話をする必要を感じない
640 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 04:59:42 ] つーか>>628 が要らんこと言ったのが悪い
641 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 23:38:14 ] シェア的にC/C++のコンパイラあげると上二つはVCとgccかなって思ってるんだが、 ベスト5ぐらいには他にどんなのがあるの?
642 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 23:54:09 ] >>641 ボーランドとかTurboとか
643 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 01:28:56 ] 当然 icc は入ると思う。
644 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 10:52:51 ] Code Warrierも入るな。間違いない。
645 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 12:31:11 ] じゃあ俺はLSI-C
646 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 17:03:07 ] codepad.org/kd2xzcnB コードパッドのほうだと期待通りに動くんですけど 僕の使ってるコンパイラ(VC++EE2008)ではdelete[]が確保したサイズじゃなくてクラスのサイズを引き数に渡してしまいます これは規格で定まっていないんじゃなくて僕が使ってるのがただのクソッタレコンパイラということですか?
647 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 17:47:50 ] >>641-645 「シェア」の意味によって違ってくるだろうな。 使ってる人数か?コンパイルされたコードの走っている台数か? 商用に限るのか?学生の講義とかも含めるのか?日本なのか世界なのか? コンパイルされたコードの走ってる台数だとOSなんかも入って ちょっとナンセンスになるから、結局人数なんだろうけど。 そうすると組み込み系とかはそんなに多くないと思う。
648 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 17:56:12 ] >>646 size_tを引数にとるoperator delete[]なんて規格にあったっけ?
649 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 18:00:26 ] ああ、そうか。メンバ関数のほうはsize_tを引数にとるのか。
650 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 21:53:50 ] 関数を作っています。 int型の引数nに応じて、配列の大きさを決めたいのですが、コンパイルすると 「定数式が必要です」とのエラーメッセージが出て失敗します。 どうすれば私の意図する動作が可能になるでしょうか? int* getTest(int n, int o[], float r) { int p[n][2];// = new int[n][2]; //省略 return *p; }
651 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 22:17:15 ] mallocもしくはnewで調べれ 配列の大きさはコンパイル時に決定されなければならない。
652 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 22:38:07 ] >>650 配列の大きさを指定できるのは一番右側のoperator[]内だけ
653 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 23:39:18 ] int (*p)[2] = new int[n][2];
654 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 23:42:36 ] >>650 関数内でnewやmallocしてそのポインタを返すのは危険きわまる。 C++なんだから、vector<vector<int>>を参照渡しするのがいいと思う。
655 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 23:44:32 ] すまぽが早く実用化されれば、こんな問題どうってことないんだけどなぁ。。。
656 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 23:55:55 ] これがJavaやC#なら、どんなオブジェクトでも平然と返せるんだけどねえ。 shared_ptrを使えばいいんだけどね。std::tr1::shared_ptr<std::string>とか 長くなりがちなのがちょっと。
657 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 00:13:10 ] どこでもshared_ptrに頼るのってどうなのよ コピーと代入のコスト結構馬鹿にならんし 寿命と例外安全考えて使わなくていいところは使わないほうがいいと思うんだし
658 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 00:41:54 ] >>653 おいデタラメ書くな
659 名前:650 mailto:sage [2009/11/11(水) 02:52:29 ] 関数を呼ぶ側が自分でvectorを宣言しなければならないのでかなり面倒ですが こんな感じでしょうか? ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10091.txt できれば関数名をsetPolygonPointsでなくgetPolygonPointsとしてvector<vector<float>>型のポインタを戻り値としたいのですが やり方がよくわかりません。 こんな感じで関数内にて、戻り値とするvを宣言すると vector<vector<float>> *v = new vector<vector<float>>; 16行目のv[c][0] = の部分をどう書いてもエラーになってしまいます。
660 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 04:08:45 ] スマートポインタ使わずに平気で関数内new&returnしてますが何か
661 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 09:13:01 ] もらったほうがきちんとすてればなんのもんだいもない
662 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 10:01:28 ] >>659 そこで new はおかしいし、それじゃインスタンス作りようないでしょ。 (vector の大きさも指定していない)単に、 vector<vector<float> > v = vector<vector<float> >(n,vector<float>(2,0)); … return v; とかいう話?(次元 nx2 で良いのか知らんが) それにしても cast をたくさん使ってるね。
663 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 10:04:12 ] 毎回floatにキャストしても CPUの中の人は結局doubleで計算するわけ?
664 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 12:14:43 ] >>663 x86系CPU+Visual C++では、そう(doubleじゃなくてlong doubleだけど)。 x64だとちょっと違ってて、多分floatで計算してると思う。 詳しくはx87FPUとSSE演算を調べてみてくれ。 重要なのはx64+WindowsだとFPUレジスタがDisableされていること。
665 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 13:50:25 ] >>660 プロジェクトに悪意あるメンバーがいたらメモリリークさせられるぞ
666 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 13:59:53 ] 悪気は無かったんです・・・
667 名前:デフォルトの名無しさん [2009/11/11(水) 14:25:35 ] VC++のMFCアプリで、あるjavaアプレットの画面イメージを取得するため 対象ウィンドウを検索して存在すればCWnd::SetWindowPos()で最前面にもってきて CWnd::RedrawWindow()で再描画、ということを行っています。 対象ウィンドウが他のウィンドウに隠れている場合はこれでいいんですが もともと最前面にある場合は、再描画の処理は不要だと思うのでスキップしたいのですが 最前面であるかどうかはどう判断すれば良いのでしょうか? CWnd::GetWindow()でいろいろやってみているんですがうまくいきません。
668 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 15:41:34 ] >>664 >x64+WindowsだとFPUレジスタがDisableされていること。 されてねえよ タスクスイッチの時もスレッド切り替えの時もちゃんとFPUはsaveするように 仕様が変わった
669 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 16:06:54 ] >>667 ::EnumWindows()とかでどうか 不安ならそれに::GetWindow()を組み合わせる
670 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 16:24:15 ] 独学でCを学んでいます。 2進数から10進数への変換方法がわかったので 入力した2進数を10進数で表示する関数を作ったのですが 32桁あるときだけ答えが空白になってしまいます。 問題がある箇所を教えてください、お願いします。 環境はxp homeのvisual studio 2005です。 kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10099.txt
671 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 16:58:16 ] ソース1とソース2のコストは同じでしょうか? CPUのコストはわかりませんが、少なくともメモリの使用量は同じに見えますが、どうでしょうか? 1: //ソース1 2: for(int i=0; i<10; i++){ 3: for(int j=0; j<10; j++){ 4: static const float x = 10; 5: //処理省略 6: } 7: } 8: //ソース2 9: static const float x = 10; 10: for(int i=0; i<10; i++){ 11: for(int j=0; j<10; j++){ 12: //処理省略 13: } 14: }
672 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:21:01 ] >>671 コンパイラと環境によって違いますとしか言えない 最適化が優れたコンパイラなら float x そのものを消去してしまうと思う
673 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:31:12 ] 使用していない変数は消去ってやつですね。 処理省略の部分でxは使っている事とします。 変数は静的な領域に確保するわけですから、どのコンパイラでもメモリの使用量はかわらないように見えるんですが、違うのでしょうか?
674 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:33:00 ] >>673 そうとも言えない とにかくコンパイラの吐いたコードを見るしか確かめる手はない
675 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:33:52 ] >>671 横から、付け加えるなら、省略された部分の処理内容も影響する。 場合によっちゃあ処理フローまでガラッと変わる。
676 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:33:57 ] あ、xは使ってるのか それなら変わらないだろうという予測が立つ しかしあくまでも予測だという事を忘れないように
677 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:36:51 ] >>673 言語仕様では、静的変数の振舞は定義されていても、実装方法までは定義されていないので、 本当に静的な領域に確保されるかどうかは、コンパイラの出力したコードを見ないとわからない。 もっとも、一度確認したからといって、次にコンパイルしたときは違う結果になっているかもしれない。
678 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:39:07 ] x86/x64のVCやgccなら、たぶん即値として命令コードに埋め込まれちゃう。 あくまで予測ですがね。
679 名前:671 mailto:sage [2009/11/11(水) 18:25:50 ] 私のレベルからしてコンパイラが吐いたコードを解析するのは無理です。 コストに関しては曖昧な感じですし for文の中に書くと気持ち悪いので、forの中でしか使わない定数でも外だししときます。 ありがとうございました。
680 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 18:46:12 ] for(int i = 0, const float x = 10; i < 10; ++i) つーか80:20の(ry
681 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 19:02:03 ] >>679 >for文の中に書くと気持ち悪いので、forの中でしか使わない定数でも外だししときます。 そりゃ逆だ。 「スコープはなるべく小さく」といわれている。
682 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 19:03:20 ] L2キャッシュが良く効くからな
683 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 19:04:03 ] じゃなかった、バグが減るからか C++はスマポがあるからいいんだが
684 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 20:45:41 ] 嘘みたいな話だが、昔の gcc だとスコープ狭い方が良 いコードが出た(龍本レベルでもあり得ないと思うんだ が…)。 しかしまぁ、人間にとってもスコープ狭い方が読むとき に気にすべき情報が減るので読み易い。
685 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 21:48:52 ] { const int c = 10; for(int j = 0; ・・・ } でもこれってちょっとダサくない? インデント深くなるし
686 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 22:05:04 ] 慣れればスコープ無視したコードの方がダサイと思うようになるさ
687 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 22:34:36 ] コピーコンストラクタとoperator=()の内容って同じことが多いのですが、 コピーコンストラクタには「*this = コピー元;」とだけ書いて operator=()のほうに処理を集約してしまうことって、なにかまずいことはありますか?
688 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 22:40:08 ] 俺もよく使うな、自動変数の生存範囲を限定するためだけのスコープ。
689 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 22:40:42 ] 場合によってはバグの元になる ならなくてもメンバ変数が全部初期化された後 すぐに代入することになるから無駄な処理が発生する
690 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 02:14:40 ] >>687 コピーコンストラクタと代入演算子で2つも似たような処理を書きたくないのなら、 逆にコピーコンストラクタ(とswap)を使ってoperator =を実装するほうがおすすめ。こんな感じ。 class Hoge { Hoge(const Hoge&); //コピーコンストラクタ void swap(Hoge& other); // *thisとotherの全メンバをswapする Hoge& operator =(const Hoge& y) { Hoge(y).swap(*this); return *this; } }; めちゃくちゃ新しい処理系ならswapの代わりにstd::moveを (ムーブ代入演算子を定義して)使う方法も使えるけど、ここでは取り上げない。あしからず。
691 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 03:17:23 ] >>690 これ未定義の動作にならない? class Hoge { int i; public: Hoge(int ii = 0) : i(ii) {} Hoge(const Hoge& j) : i(j.i) {} //コピーコンストラクタ void swap(Hoge& other) { // *thisとotherの全メンバをswapする Hoge* tmp = new Hoge; std::memcpy(tmp, this, sizeof(*this)); // undefined behavior std::memcpy(this, &other, sizeof(*this)); std::memcpy(&other, tmp, sizeof(*this)); } Hoge& operator=(const Hoge& y) { Hoge(y).swap(*this); return *this; } void print() const { std::cout << i << std::endl; } }; int main() { Hoge a(1); Hoge b(2); a = b; a.print(); b.print(); }
692 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 04:00:58 ] 質問です C++において、関数ポインタを使う意義は何があるでしょうか? 言い換えれば、具体的にどのような事をするときに便利なのでしょうか どなたかお願いします・・・
693 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 04:48:35 ] コールバックとか。・・・でもC++だとその多くは仮想関数に取って代わるかな? C++でも使う例というと、関数テーブルかなぁ。 たとえば、ユーザーの入力したコマンドに応じた動作をしたい場合(以下コードは適当)、 typedef int(*Cmd)(T* args); Cmd command = { &CommandA, &CommandB ... }; // 関数テーブル(関数ポインタのリスト) みたいなのを用意した上で、それをこんな風に実行する。 int Execute(int cmd, T* args) { return (command[cmd])(args); } // cmdの値はユーザーの入力次第 もちろん、switch (cmd) { ... } で分岐させてもいいけど、それだと各コマンドに対応する関数を 色々切り替えたい時とかには少々不便だし、コマンドの総数が3桁だったりするとswitch文が長すぎちゃう。 まぁその辺は結局作りたい物次第なわけだけど。 世の中に無数にあるはずの、オリジナルのスクリプト言語(ゲームエンジン用でも何でも)のコードには、 関数テーブルが山ほど出てきそうだなぁ。
694 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 09:09:50 ] 最近の OO 学習から入った C++ な人は基底クラスのポ インタ使ってれば無理に関数ポインタ使わなくてもいい 気がする。
695 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 09:36:52 ] クラスのインスタンスのメソッドへのポインタって使えますか?
696 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 10:10:15 ] はい
697 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 12:27:45 ] >>692 Win32を使うと嫌でもコールバックを使う場面に出くわすよ
698 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 16:09:11 ] >>695 使えるけど使わないほうが無難だな。 ->* とか .* とか見たくないよ。 C++的には operator()()がいいかも。
699 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 20:26:12 ] ->*は拡張メソッドで使ってしまう
700 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 21:49:51 ] Cです 構造体の初期化でmemsetを使うと問題があると聞きました. ループ文でまわしている場合,毎回初期化する必要があるんですが どうすればいいんでしょうか? ポインタ配列です. typedef struct{
701 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 21:52:43 ] struct Hoge hoge = {0};
702 名前:700 mailto:sage [2009/11/12(木) 21:52:57 ] すいません.途中で送信してしまいました. どうやって初期化すればよろしいのでしょうか?
703 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 22:24:39 ] >>701 ありがとうございます. 実際にはポインタで宣言しているのですが, Hoge *hoge hoge = malloc(sizeof(Hoge) * 100); for(i = 0; i < 100; i++){ hoge[i] = {0}; } でいいんですかね?
704 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 22:32:05 ] zeromemory使えや
705 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 22:53:04 ] std::fill()使えや
706 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 22:57:05 ] >>705 それはC++。
707 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 22:59:33 ] >>703 だけ見てCかC++か区別付くかヴォケ
708 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 23:00:04 ] Hoge foo = {0}; for(i = 0; i < 100; i++) hoge[i] = foo;
709 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 23:00:35 ] C++ならmalloc()の戻り値をキャストしないのはエラーなのでは
710 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 00:44:58 ] Hoge の中に微妙なモノが union で詰まってる時は必要 に応じて何種類か用意しておいてコピーすればいいと思 うんだけど、この場合何も考えずに {0} で初期化する と未定義動作だっけ?
711 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 01:01:58 ] HogeがPODじゃない場合はそもそもそういう初期化は出来ない
712 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 01:55:16 ] >>707 この質問は>>700 だぞ? 一行目でちゃんと「Cです」って言ってるじゃん。 「>>703 だけ見て」ってお前、>>703 だけ見ること自体がヴォケなんだよw
713 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 07:12:50 ] >>646 規格の 12.5 p5 で、解放されるメモリブロックのサイズが渡されると 定められている。 > When a delete-expression is executed, the selected deallocation function > shall be called with the address of the block of storage to be reclaimed > as its first argument and (if the two-parameter style is used) the size > of the block as its second argument. かなり古い VC についてはバグとして見つかっていたみたいだけど、 新しいのでも直ってないのかな? ml.tietew.jp/cppll/cppll/thread_articles/5126
714 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 10:25:48 ] 結論、そのコードがCで、今後C++に転用する可能性を排除できるのならmemset()でもいいんでない? そうでないなら、>708で。間違っても、一部のロートルの世迷言に釣られてmemcpy(hoge + i, & foo, sizeof(foo))なんてしないように。
715 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 10:53:37 ] >>711 こういうことなんだが。 struct { union { void *p; void (*func)(void); float f; double d; } u; } s = {0};
716 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 10:56:01 ] >>715 今規格見た。最初のメンバが初期化されるんだな。
717 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 11:59:14 ] unionを{0}で初期化してもいいけど 最初のメンバと違う型で参照したら処理系依存ってことか
718 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 12:47:56 ] EUCで「。」の区切りを見つけるにはどうすればいいですか 文字コードは0xa1 0xa3です。 偶然にaaaa 0xa1、0xa3 bbbb となった場合が判断できないですが。
719 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 12:59:15 ] >>718 探したい対象が文字列のように、EUCエンコードされていることが保証されているなら、 0xa1から遡って0x80以上のコードが偶数個連続していたらその0xa1が1バイト目。 遡るのが嫌なら、先頭から監視するしか。
720 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 13:02:24 ] 実行ファイルやDLLに画像など任意のバイナリデータを埋め込むにはどうするればいいんでしょうか? 今考えてるのは、unsigned char配列にデータを読み込んで0xXX, 0xYY, 0xZZ, ・・・のような形式で出力するプログラムを作り コンパイル前に一度実行してdata.datに保存。利用者側は unsigned char data[] = { #include "data.dat" }; と書いて使う。という感じなんですが・・・
721 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 13:07:32 ] >>719 トンクス
722 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 13:09:09 ] >>720 windows限定なら、標準のリソースとして埋め込めばいいのでは。アイコンなど。
723 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 13:53:35 ] >>719 文字化けや不要コードの埋め込みなどが原因と思うけど いい具合に出来なかった。
724 名前:718 mailto:sage [2009/11/13(金) 14:05:36 ] 変換ツール任せでやってみる。wstring型に変換できれば比較は簡単だから。
725 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 14:21:20 ] wchar_tに変換して出来ました。 手間かかるけど、文字化け多発するよりかは良いか。
726 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 15:47:40 ] vs2008なのですがboostのshared_ptrでインテリセンスって使えますか? 試したところ効かなかったのですが using boost::shared_ptr; shared_ptr<Hoge> pHoge = shared_ptr<Hoge>( new Hoge( 3 ) ); pHoge-> ↑で出したい
727 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 16:18:31 ] std::tr1::shared_ptrなら出るよ。
728 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 16:45:12 ] C++の識別子長すぎていらつく スコープ付きの識別子の別名定義ができれば便利なのに
729 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 16:51:33 ] つスコープ内でtypedef
730 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 16:52:48 ] 725だけど、「。」の発見は出来たけど、こんどは文字種の特定が困難になったよ。 かな、カナ、漢字など。UTF16らしいが文字コードがよくわからん。 EUC -> UTF16 -> SJIS OR EUCと何度も変換するしかないのか。
731 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 17:11:00 ] >>727 試したけどダメっぽいです。コンパイルは通るんですが 何か根本的な間違いをしてるのかも・・・。 ひとまず諦めます
732 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 17:13:00 ] >>729 それじゃ型限定じゃん 変数や関数の別名を参照や関数ポインタ使わずに楽に短くしたいんだよ
733 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 17:16:05 ] >>731 インテリセンスするための情報収集が狂っちゃうと、そういうことがおきるねー リビルドや 中間ファイル(.obj や .res .scc .pdb .pch .ilk .idb .ncb .plg .bsc まだあるかも)を完全に消してのビルドで 復活したりするよ。
734 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 17:40:31 ] >>732 C#のusing的なやつ(しかもスコープ限定)が欲しいってことか。
735 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 18:07:55 ] >>730 混ぜるな危険
736 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 18:18:15 ] >>714 まぁ俺も sockaddr_in 辺りは memset でクリアしちゃ うけどさ。 > そのコードがCで、今後C++に転用する可能性を排除で > きるのならmemset()でもいいんでない? 厳しく言うと >>715 みたいなのは union を struct に しても memset はアウトだよな?
737 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 19:05:49 ] [迷信] とりあえず memset で初期化 www.kijineko.co.jp/tech/superstitions/initialization-by-memset.html
738 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 20:29:57 ] >>737 リンク先あっているのか? A a[10] = {0} で a[0]〜a[9] のすべてが0クリアされるのか? static なら保障されているが、auto な配列ではダメなのでは?
739 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 20:30:49 ] されるよ ダメくない
740 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 20:44:04 ] >>739 確認しました。 明示的に初期化される、ただし、一部しか明示されていない場合は、残りは 0 で初期化される、これは auto でも static でも同じとのことですね。 thanks a lot.
741 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 23:45:42 ] >>733 もしやと思ってSP1にアップデートしたらstd::tr1::shared_ptで出来ました! 今までアップデートしてなかったんだなぁ…
742 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 03:37:57 ] sscanfでは、第一引数の文字列の 半角スペースのある領域を""で囲っても、 ひとつの区切りとしてくれないみたいですが、 それができる方法がありましたら教えてください。 sscanf("\"abc de\" 5", "%s%s", s1, s2);
743 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 03:39:42 ] >>742 面倒でもstrtok()使え
744 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 03:46:13 ] *scanf は糞
745 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 04:23:51 ] >>743 >>744 ありがとうございます。 やはり、自前で実装ですか・・ やってみます。
746 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 04:31:30 ] parserつかえ
747 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 04:51:18 ] >>746 ありがとうございます。 試してみます。
748 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 05:52:57 ] >>742 "%s"ではなく、"\"[^\"]"を使えばOK!
749 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 07:21:31 ] 構造体の配列について質問です 構造体Aを A **a で定義し a[x][y] でメモリを確保して他の関数に引数として渡します その際 test_func(**a) test_func(*a[y]) test_func(a[][y]) で全て同じ定義だと思うのですが全て関数の中で a[i][j]でアクセスできますよね (ただし i <= x && j <= y) 二つ目と三つ目では[y]で定義しているのでアクセス可能かと思いますが 一つ目はどうやって認識しているのですか?
750 名前:デフォルトの名無しさん [2009/11/14(土) 07:23:15 ] unsigned long からfloatに変換した場合、起こりうる問題を教えてください
751 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 07:38:56 ] >>750 有効桁数が減ります
752 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 07:55:40 ] >>749 アクセスの仕方は一緒でも 渡されるものの内容が違います
753 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 08:49:47 ] >test_func(**a) >test_func(*a[y]) >test_func(a[][y]) >で全て同じ定義だと思うのですが ちがいます
754 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 09:51:11 ] >>753 一つ目と二つ目は違いますが二つ目と三つ目はおなじですよね? ポインタのポインタとして渡された先頭のアドレスが渡された関数で アドレスしか渡してないのにその内部構造が定義したように認識されているのはなぜなのでしょうか?
755 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 09:54:11 ] >>754 二番目と三番目で渡している型は 配列を指すポインタであって、ポインタのポインタではありません
756 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 09:58:06 ] >>754 少なくとも2と3はまったく違う 1と2は一緒とみなしてよいときとそうではない場合がある
757 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 11:56:11 ] >>748 ありがとうございます。 試してみます。
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を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。