1 名前:デフォルトの名無しさん [2008/09/06(土) 22:45:12 ] エスケープシーケンスやWin32APIなどの環境依存なものでもOK。 ただしその場合、質問者は必ず環境を書きましょう。 ※sage禁止です(と代々スレに書いてありますが自己判断で)。 【前スレ】 【初心者歓迎】C/C++室 Ver.58【環境依存OK】 pc11.2ch.net/test/read.cgi/tech/1218023777/ 【アップローダー】(質問が長い時はココ使うと便利) kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm ◆ソースのインデントについて 半角やTABでのインデントはスレに貼ると無くなります。 そのため、アップローダーに上げるのが最も良いですが、 直接貼るのであれば、全角空白か に置換しておくことをお勧めします。
152 名前:デフォルトの名無しさん mailto:sage [2008/09/11(木) 23:30:09 ] もうCは難しすぎるからやめた!
153 名前:デフォルトの名無しさん [2008/09/11(木) 23:30:10 ] 150は本物です。 その方法は、メモリマップドファイルでサイズ指定してDLLに渡すんです。 でもこれだと、exeしか提供されていない場合は出来ません。 exeでも出来る方法はありませんか
154 名前:デフォルトの名無しさん mailto:sage [2008/09/11(木) 23:36:51 ] DLLだって、DLLしか提供されてなかったら、渡すほうから勝手に渡し方を決められないだろ。
155 名前:デフォルトの名無しさん [2008/09/11(木) 23:39:38 ] ついに中国共産党の幹部が動き出したぞ!
156 名前:デフォルトの名無しさん [2008/09/11(木) 23:39:51 ] DLLの場合は、ポインタchar *で渡すので同時にサイズを指定できるんです。 exeはファイルしか入力できないので、そのままだと1G全部処理してしまいます。 なんとかなりますか?
157 名前:デフォルトの名無しさん mailto:sage [2008/09/11(木) 23:43:23 ] 通信しろよ
158 名前:デフォルトの名無しさん [2008/09/11(木) 23:48:10 ] まずこれがわかりません。 1Gのファイルを先頭100Mだけ残して縮めるのはどうしたらいいですか? あと、100Mと900Mのファイルをコピー無しに連結するのはどうしたらいいですか? どちらも書き込み不可にしておけば目的を達成できます。
159 名前:デフォルトの名無しさん mailto:sage [2008/09/11(木) 23:49:44 ] うぜぇな。 しらねぇよ。 NTFSとMFTでもググって勝手にやれ。
160 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 00:01:29 ] >>156 154無視かよ、俺じゃないけど。 それはEXEだから、DLLだから、という問題ではない。 EXEでもファイル名と、そのうち何バイト目から何バイト目だけを処理するって オプションを指定できるようになっているものだってあるし、 DLLでも\0終端文字列を受け取るので、バイト数を直接的に指定できないってものもある。
161 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 00:10:02 ] バイナリデータならサイズ指定出来るのは普通ですよ。あとEXEにファイルを渡す場合、内容が見えないのに何バイト目からいくらまでとか指定は困難では? 縮小、結合方法を教えてもらいたいです。
162 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 00:40:41 ] constの付いたポインタは、const_cast使えばconstをはずせますが、 constの付いたポインタでない普通の変数(intとかdoubleとか)のconstを 一時的にはずす方法ってありますか?
163 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 01:09:47 ] *(type-name *)&variable = rvalue const int i = 10; *(int *)&i = 20; i = 30; 見なかったことにしてくれ
164 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 01:18:35 ] int& j = *const_cast<int*>(&i);
165 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 01:24:12 ] >>164 int& j = const_cast<int&>(i);でおk
166 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 01:30:27 ] >>161 関数にファイルを渡す場合、内容が見えないのに何バイト目からいくらまでとか指定は困難では? って言ってるのと同じに見える で、知りたいのは ・1つのファイルを、メモリに読み込むことなく分割する方法 ・2つのファイルを、メモリに読み込むことなく結合する方法 ってこと?それならたぶん無理だと思う そもそも、ファイルの内容をメモリに読み込まないと、ファイルの操作ができないから >>138 を見ると、どこで100M分余計にメモリを食うのかわからない。 dll なり exe なりに渡すとコピーが発生するって事? >>142 からそんな風に感じたんだけど。 でも>>149 見ると、その dll や exe が受け取ったデータのコピーを取るとは思えない。 ファイルの中身をメモリに読み込むのが『余計』だと考えてるなら、これは余計じゃないんで効率化は無理 10Mずつ読み込むとか、そういう解決方法しかないと思うよ 結論:何をしてるのか、何がしたいのか、が分からない。今やってることをそのまま書いた方が分かりやすいかもよ
167 名前:162 mailto:sage [2008/09/12(金) 01:52:35 ] >>164 >>165 (同じ人?) ありがとうございます。
168 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 02:16:59 ] inodeでぐぐる?
169 名前:162 mailto:sage [2008/09/12(金) 02:25:10 ] 続けて質問してしまいますが、お願いします。 typeid()を使っているのですが、 typeid(hoge).name()で帰ってくる文字列が本やサイトに載っているのと異なっています。 例えば、 int i; -> i string s; -> Ss vector<int> vi; -> St6vectorIiSaIiEE vector<vector<double> > vvd; -> St6vectorIS_IdSaIdEESaIS1_EE complex<int> ci; -> St7complexIiE class Test0{}; Test0 t0; -> 4Test という感じ(一部省略)になります。 なんとなく分かるのですが、完全には解読できません。 この表記の見方、もしくは解説サイトなどありましたら教えて下さい。
170 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 02:28:23 ] typeid(Type).name()はoperator=とoperator!=で比較するしか 意味がない。 返される文字列は処理系依存。だが異なる型は異なる文字列 になる事は保証されている。
171 名前:169 mailto:sage [2008/09/12(金) 03:03:42 ] >>170 ありがとうございます。 具体的に書いた方が良さそうなので、書きます。 今、 template<typename T> class Matrix{ private: vector<vector<T> > _matrix; ・・・ }; のような行列クラスを作成しているのですが、 行列を要素に持つ行列を考慮したいので、 T が Matrix<int> というのも考えられます。 行列の中身を参照(表示)するときに、 行列の要素の型がintやdoubleなどの場合と、 行列の要素の型がMatrixの場合とを区別するために、 typeid()を使って,Tの構造を知ろうと思っています。 なので、name()をうまく解読できればと思いました。 方向性自体ダメですか?
172 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 03:11:10 ] ダメダメだね。name()はそんなことに使えない。 それこそ"type0", "type1"みたいな連番でも構わないわけだし。 素直に特殊化で頑張ってください。
173 名前:169 mailto:sage [2008/09/12(金) 03:47:41 ] >>172 ありがとうございます。 便利なの見付けたと思ったのですが、 >それこそ"type0", "type1"みたいな連番でも構わない その通りですね。 出直してきます。m(_ _)m
174 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 06:03:33 ] PERL RUBY Pythonをcから使いたいとき、どれが最も必要なファイルが少なく済みますか? 合計のファイルサイズが小さい順に押してください。
175 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 06:38:55 ] IronPythonにきめました。C++(API)もC$(NET)も利用できてコンパイルして実行ファイルが作れるらしいです。
176 名前:デフォルトの名無しさん [2008/09/12(金) 06:40:46 ] よかったですねkがんばってください
177 名前:90 [2008/09/12(金) 07:46:35 ] >>127 名前をつけるという方法で解決はできるのですが、 何かライブラリとかで提供されてきたstructとかだったら、勝手に型名をつけられないなぁと。 それか、型名無しだから名前を勝手につけても問題はない・・・ということになるのでしょうか。 その後いろいろやってたらunionを入れなくても、 struct中に2つ以上の型名のないstructをいれても2つめからのstructで>>90 と同じエラーになります。 エラーは「error C2664: 'func' : 1 番目の引数を '' から '&' に変換できません。」とでます。
178 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 08:06:41 ] DuplicateHandleの効果を教えてください。コピーを作らずにsi.hStdOutput = hd;と書くと出力されません。 f(){ HANDLE hd, he; hd = CreateFile("out.dat", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0 ); DuplicateHandle(GetCurrentProcess(), hd, GetCurrentProcess(), &he, 0, 1, DUPLICATE_SAME_ACCESS); STARTUPINFO si; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; si.hStdOutput = he; PROCESS_INFORMATION pi; pi.hProcess = NULL; CreateProcess(NULL, "xdoc2txt a.doc", NULL, NULL, TRUE,0, NULL, NULL, &si, &pi ); WaitForSingleObject(pi.hProcess,INFINITE);}
179 名前:デフォルトの名無しさん [2008/09/12(金) 10:08:18 ] C++についての質問です。 ファイルを単純にコピーするとき、次の二つの実行速度はどっちが速いですか? //A ifstream fl_in("file1.txt", ios::in| ios::binary); ifstream fl_out("file2.txt", ios::out| ios::binary); char ch_get; while(!file1.eof()){ ch_get= fl_in.get(); if(!file1.eof()) fl_out.put(ch_get); } //B copy(istreambuf_iterator<char>(fl_in), istreambuf_iterator<char>(), ostreambuf_iterator<char>(fl_out)); copyは<algorithm>のです。 もっと高速に処理できるコードがあったら、そちらもよろしくお願いします。
180 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 10:09:54 ] 実測したわけじゃないが、Cライブラリのfread fwriteを使った方が速いらしい。
181 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 10:13:36 ] WindowsAPIが最速なことは間違いない。 Cはコスト掛けた上で最後にAPIを呼ぶ。
182 名前:デフォルトの名無しさん [2008/09/12(金) 10:15:28 ] ありがとうございます。 今度試して見ます。 fread,fwriteで思い出しましたが、c++のread, write関数との速度の違いはいかがでしょうか? 自分としては、freadやfwriteは、使い勝手の面で、境界越えしそうで怖いのですが。
183 名前:デフォルトの名無しさん [2008/09/12(金) 10:40:48 ] Vistaのイベントログに重大のクラスのイベントを書き込みたいです。 ReportEventで何を渡せばいいのでしょうか? 調べたのですが重大だけが見つかりませんでした。。。
184 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 10:49:23 ] fread/fwriteは移植用で実際はネイティブのAPIを呼ぶ。 ネイティブAPIを避けるため、普通ならfwriteを呼ぶのがいい。
185 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 10:53:38 ] Windowsでスクロール付きのテキスト表示エリアを簡単に作れるライブラリはありませんか?
186 名前:デフォルトの名無しさん [2008/09/12(金) 10:55:06 ] ありがとうございます。 fwriteでがんばります。
187 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 12:16:10 ] >>185 エディットコントロール
188 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 12:26:10 ] トンクス
189 名前:デフォルトの名無しさん mailto:sage [2008/09/12(金) 17:10:52 ] >>186 fread、fwriteは2Gまでの制限があるから注意な
190 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 00:50:04 ] >>178 CreateFileするときにSECURITY_ATTRIBUTESで継承を許可(bInheritHandle = TRUE)にしておけば、 CuplicateHandleは要らないはず。
191 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 04:30:38 ] >>185 C++Builder使え
192 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 17:00:13 ] 2の26乗 (=N) 個の配列どおしの要素を掛けた物の総和を求めたいと思います。 (a,b,c・・・) (x,y,z・・・)とするとき、ax + by + cz + ・・・です。 これを4スレッドに分けて計算したら早くなりますでしょうか? 0〜N/4、 N/4+1〜・・・と分割して和を求めるってことです。
193 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 17:01:25 ] シングルコアでやったらまず間違いなく遅くなる
194 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 17:35:11 ] >>192 寧ろ4で割った余りが0,1,2,3でスレッドを分けた方が早いかもよ。 特にIntelの2コアや4コアの場合。
195 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 19:59:55 ] >>192 Pen4,Core2Duo,AMD系ではおそらく逆に遅くなる Core2Quadなら上手くやれば早くなる 環境依存だけどプロセスの優先度上げて、 コンテキストスイッチ減らした方が良いんじゃない?
196 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 20:47:34 ] >>192 スレッド数が物理コア数以下なら速くなるはずだけど その処理内容だとメモリアクセスがボトルネックになりそう。 SIMDなんかがある環境ならそれ使うようにオプション指定するなり インラインアセンブラ使うのもいいんじゃないか。
197 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 20:48:36 ] 1コアです。 のろくなります。 分割します。 #include <iostream> #include <windows.h> #include <process.h> using namespace std; #define N 110108864 char *a,*b; unsigned int s[4]; unsigned int f(void){unsigned int sum=0; for(int n=0;n<N;n++)sum+=a[n]*b[n];return sum;} unsigned WINAPI g0(void*){for(int n=0;n<N/2;n++)s[0]+=a[2*n]*b[2*n];return 0;} unsigned WINAPI g1(void*){for(int n=0;n<N/2;n++)s[1]+=a[2*n+1]*b[2*n+1];return 0;} unsigned int g(void){ s[0]=s[1]=0; HANDLE hd[2]; hd[0]=(HANDLE)_beginthreadex(NULL, 0, g0,NULL, 0 ,NULL); hd[1]=(HANDLE)_beginthreadex(NULL, 0, g1,NULL, 0 ,NULL); WaitForMultipleObjects(2, hd, TRUE, INFINITE); CloseHandle(hd[0]);CloseHandle(hd[1]); return s[0]+s[1];} unsigned WINAPI h0(void*){for(int n=0;n<N/4;n++)s[0]+=a[4*n+0]*b[4*n+0];return 0;} unsigned WINAPI h1(void*){for(int n=0;n<N/4;n++)s[1]+=a[4*n+1]*b[4*n+1];return 0;} unsigned WINAPI h2(void*){for(int n=0;n<N/4;n++)s[2]+=a[4*n+2]*b[4*n+2];return 0;} unsigned WINAPI h3(void*){for(int n=0;n<N/4;n++)s[3]+=a[4*n+3]*b[4*n+3];return 0;} unsigned int h(void){ s[0]=s[1]=s[2]=s[3]=0; HANDLE hd[4]; hd[0]=(HANDLE)_beginthreadex(NULL, 0, h0,NULL, 0 ,NULL); hd[1]=(HANDLE)_beginthreadex(NULL, 0, h1,NULL, 0 ,NULL); hd[2]=(HANDLE)_beginthreadex(NULL, 0, h2,NULL, 0 ,NULL); hd[3]=(HANDLE)_beginthreadex(NULL, 0, h3,NULL, 0 ,NULL); WaitForMultipleObjects(4, hd, TRUE, INFINITE); return s[0]+s[1]+s[2]+s[3];}
198 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 20:49:36 ] main(){ cout<<"初期値設定中・・・\n"; a=new char[N] ; b=new char[N] ; int n,cl; for(n=0;n<N;n++){int x=rand(); a[n]=(char)(x&15); b[n]=(char)((x>>4 )&15); } cout<<"計測開始・・・\n"; cl=GetTickCount(); cout<<"1 スレッド 計="<<f()<<" 掛かった時間="; cl=GetTickCount()-cl; cout<<cl<<endl; cl=GetTickCount(); cout<<"2 スレッド 計="<<g()<<" 掛かった時間="; cl=GetTickCount()-cl; cout<<cl<<endl; cl=GetTickCount(); cout<<"4 スレッド 計="<<h()<<" 掛かった時間="; cl=GetTickCount()-cl; cout<<cl<<endl;}
199 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 21:02:22 ] 手間の掛かる処理にしてみました。浮動小数点の割り算。2スレッドが早くなりました。 #include <iostream> #include <windows.h> #include <process.h> using namespace std; #define N 10097152 double *a,*b; double s[4]; double f(void){s[0]=0; for(int n=0;n<N;n++)s[0]+=a[n]/b[n];return s[0];} unsigned WINAPI g0(void*){for(int n=0;n<N/2;n++)s[0]+=a[2*n]/b[2*n];return 0;} unsigned WINAPI g1(void*){for(int n=0;n<N/2;n++)s[1]+=a[2*n+1]/b[2*n+1];return 0;} double g(void){ s[0]=s[1]=0; HANDLE hd[2]; hd[0]=(HANDLE)_beginthreadex(NULL, 0, g0,NULL, 0 ,NULL); hd[1]=(HANDLE)_beginthreadex(NULL, 0, g1,NULL, 0 ,NULL); WaitForMultipleObjects(2, hd, TRUE, INFINITE); CloseHandle(hd[0]);CloseHandle(hd[1]); return s[0]+s[1];} unsigned WINAPI h0(void*){for(int n=0;n<N/4;n++)s[0]+=a[4*n+0]/b[4*n+0];return 0;} unsigned WINAPI h1(void*){for(int n=0;n<N/4;n++)s[1]+=a[4*n+1]/b[4*n+1];return 0;} unsigned WINAPI h2(void*){for(int n=0;n<N/4;n++)s[2]+=a[4*n+2]/b[4*n+2];return 0;} unsigned WINAPI h3(void*){for(int n=0;n<N/4;n++)s[3]+=a[4*n+3]/b[4*n+3];return 0;} double h(void){ s[0]=s[1]=s[2]=s[3]=0; HANDLE hd[4]; hd[0]=(HANDLE)_beginthreadex(NULL, 0, h0,NULL, 0 ,NULL); hd[1]=(HANDLE)_beginthreadex(NULL, 0, h1,NULL, 0 ,NULL); hd[2]=(HANDLE)_beginthreadex(NULL, 0, h2,NULL, 0 ,NULL); hd[3]=(HANDLE)_beginthreadex(NULL, 0, h3,NULL, 0 ,NULL); WaitForMultipleObjects(4, hd, TRUE, INFINITE); return s[0]+s[1]+s[2]+s[3];}
200 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 21:03:09 ] main(){ cout<<"初期値設定中・・・\n"; a=new double[N] ; b=new double[N] ; int n,cl; for(n=0;n<N;n++){int x=rand(); a[n]=1+(double)(x&15); b[n]=1+(double)((x>>4 )&15); } cout<<"計測開始・・・\n"; cl=GetTickCount(); cout<<"1 スレッド 計="<<f()<<" 掛かった時間="; cl=GetTickCount()-cl; cout<<cl<<endl; cl=GetTickCount(); cout<<"2 スレッド 計="<<g()<<" 掛かった時間="; cl=GetTickCount()-cl; cout<<cl<<endl; cl=GetTickCount(); cout<<"4 スレッド 計="<<h()<<" 掛かった時間="; cl=GetTickCount()-cl; cout<<cl<<endl;}
201 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 21:06:39 ] 1CPUなのに2スレッドは凄い効果あります。およそ倍速出ます。 何度もメモリ読んでいるうちに、キャッシュが効いたりするのではと思い 一番最後にもう一度1スレッドを計算しても速度ははじめと同じでした。
202 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 21:13:22 ] >>201 こっちの方が早くね? 主な変更はローカル変数 x の導入 unsigned WINAPI g0(void*dummy){unsigned int x=0;char *p=&a[0],*q=&b[0];for(int n=0;n<N/2;n++)x+=p[n]*q[n];s[0]=x;return 0;} unsigned WINAPI g1(void*dummy){unsigned int x=0;char *p=&a[N/2],*q=&b[N/2];for(int n=0;n<N/2;n++)x+=p[n]*q[n];s[1]=x;return 0;}
203 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 21:23:58 ] BCC2009の速度最適化したときの数値は1700 clockくらいなんですが、 VC++2008の速度最適化したときの数値は250 clockくらいです。 BCCの速度が鈍いだけで。VC++2008だと、1スレッドが最も速かったです。 >>202 このようにしてもVC++では大して効果なく1スレッドが最速でした。1コアCPUなんですが。 unsigned WINAPI h0(void*){int m=0; double x=0; for(int n=0;n<N/4;n++){x+=a[m]/b[m];m+=4;} s[0]=x; return 0;}
204 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 21:44:21 ] CPUによって違うだろ。Core2使ってるの? Athlon64だとどちらも1スレッド>2スレッド>4スレッドとなる。 近々X2かPhenom買うのでそちらも試してみたい。
205 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 22:15:20 ] 初期のセレロンの1コア2GHzですよ
206 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 22:19:00 ] NetBurst系は他のCPUとはかなり異質な結果が出るらしいからなあ
207 名前:デフォルトの名無しさん mailto:sage [2008/09/13(土) 23:31:29 ] すみません、初心者な私に教えて下さい。 #include <list> using namespace std; class C { public: int ic; C (int c) { ic = c; } }; int main() { list<C *> mylist; mylist.push_back( new C(0) ); mylist.push_back( new C(1) ); mylist.push_back( new C(2) ); } こんな感じになってるとして、ic == 1 であるようなオブジェクトだけを、 ・list から削除し、 ・かつ delete する には、どのように書けばよいのでしょう。
208 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 00:32:06 ] #include <iostream> #include <list> #include <algorithm> using namespace std; class C { public: int ic; C (int c) { ic = c; } ~C() { cout << "~C" << endl; } }; struct delete_equal_to: public std::binary_function<C *, int, bool> { bool operator ()(C * p, int c) const { return (NULL != auto_ptr<C>(p->ic == c ? p: NULL).get()); } }; int main() { list<C *> mylist; mylist.push_back( new C(0) ); mylist.push_back( new C(1) ); mylist.push_back( new C(2) ); cout << mylist.size() << endl; mylist.remove_if(bind2nd(delete_equal_to(), 1)); cout << mylist.size() << endl; }
209 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 00:41:07 ] >>208 returnの中はp->ic == cだとだめなの?って書こうとしたが、deleteさせる意図があるのね。 そこまでするくらいなら、list<shared_ptr<C> >使えよって言ってやるべきだと思う。
210 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 00:45:31 ] 「まだ」C++標準ではないのでね。
211 名前:207 mailto:sage [2008/09/14(日) 00:57:04 ] ぐっは、難しい…。 もしかしてさらっと書ける構文とかあるのかと思ったら、そうでも無いのですね。 でも一つずつ読解してみます。 ありがとうございました!
212 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 00:59:34 ] ついでに言っておくけど mylist.push_back( new C(0) ); はpush_backに失敗するとnew C(0)したオブジェクトがリークする
213 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 01:15:33 ] 馬鹿な私に教えて下さい。 宿題板で、作って頂いたc++なのですが習ってない部分も出ていて、 よくわからず、困っています。 習っていない関数を使うのには、特に問題はないのですが 提出の際に説明書っぽいのをつけるのですが作成できず困っています。 例えば、この作業をするには?とか、オプションでこんな事も出来ます とかです。 スレチかもしれませんが、宜しくお願いします。 ちなみに、宿題板ではボロボロに言われ、ここにきました。 すいません。 kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/7720.txt
214 名前:207 mailto:sage [2008/09/14(日) 01:18:29 ] なるほど…。 ということは、push_back() の引数として直接与えるんじゃなくて、 いったん C *p = new C(0); して、とりあえず mylist.push_back( p ); としてみて、 std::bad_alloc が投げられたらあきらめて delete する、 みたいな感じでしょうか。
215 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 01:22:08 ] >>213 そんなの一から読めって言うのかよ。 大まかな機能ぐらい説明しろよ。 お前が作らせたんなら分かるだろうが。 というか、宿題スレ池。 C/C++の宿題を片付けます 115代目 pc11.2ch.net/test/read.cgi/tech/1217741118/
216 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 01:29:56 ] >>215 わかりました。宿題スレに行きます。 すいませんでした。ご迷惑お掛けしました。 ちなみに、内容はエンコドとデコドで テキストを吐き出し、オプションでプリントするみたいな感じです。 失礼しました。
217 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 01:33:41 ] 見たけどコメントついてるじゃん 無理せずに単位落としたら?
218 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 01:36:08 ] >>214 bad_allocが投げられたらdeleteする必要はないぞ。
219 名前:207 mailto:sage [2008/09/14(日) 01:42:05 ] >>218 了解しました。 どうもありがとうございます。
220 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 02:24:00 ] >>218 お前は読み間違えてる
221 名前:207 mailto:sage [2008/09/14(日) 02:29:02 ] >>220 あ、やっぱ delete(p); は必要ですか。 ていうか私が言葉足らずでした。
222 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 03:02:24 ] std::bad_alloc例外が投げられるという事はメモリ確保に 失敗しているのだから、deleteしたらまずいだろう
223 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 03:37:51 ] こういうことだろ。bad_allocを投げるのはmylist、pはdeleteしないといけない。 C *p = new C(0); try { mylist.push_back(p); } catch (std::bad_alloc const&) { delete p; throw; } auto_ptrでもいける。 std::auto_ptr<C> p(new C(0)); mylist.push_back(p.get()); p.release();
224 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 03:54:17 ] >>223 ああそういう意味かごめん そりゃdeleteは必要だわ newとpush_backを分離する事を前提とした 話なのね
225 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 06:23:11 ] >>207 さらっと、というか自分でループまわす構文はあるよ。 STL的ではないけど。 for(list<C *>::iterator it=mylist.begin(); it != mylist.end();) { // 1なら if((*it)->ic == 1) { delete *it; it= mylist.erase(it); } // 1じゃないなら else { ++it; } }
226 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 06:53:47 ] 確かboostだとこう書ける #include <boost/ptr_container/ptr_list.hpp> typedef boost::ptr_vector<C> list_type; //ポインタ指定しないが、中身はポインタになる list_type mylist; mylist.push_back( new C(0) ); 〜 for(list_type::iterator it = mylist.begin(); it != mylist.end();) { if(it->ic == 1) { it = mylist.erase(it); //消去動作で自動でdeleteされる } 〜 //あとは225と一緒 詳細 ttp://www.kmonos.net/alang/boost/classes/pointer_container.html
227 名前:207 mailto:sage [2008/09/14(日) 10:05:26 ] >>223 > こういうことだろ。bad_allocを投げるのはmylist、pはdeleteしないといけない。 あ、そうです。言葉足らずというのはそれが言いたかったのでした。 >>225 おおお、これです。こんな感じのを期待していました! > STL的ではないけど。 というのは、イテレーションしていく過程はあくまでイテレータにまかせるべきで、 「it= mylist.erase(it);」のような「つなぎかえ」(?)のようなことを外野がやるのは スマートじゃない、ということでしょうか。 うーむ、「実行時に動的に new したものを連結させておき、いらなくなったらそこだけ外す」 というのは良くあるケースかと思っていたのですが、もしかしてそもそもデータ構造の 選び方が間違ってますか……? >>224 氏も、 > newとpush_backを分離する事を前提とした > 話なのね とおっしゃってるし……。 >>226 いろいろな環境で動かしたいのでできれば boost は避けたいのですが、 でも勉強になります。特にリンク先の「etc」のところ。 ありがとうございます。
228 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 16:03:52 ] >>227 boostって静的リンク(?)だから大丈夫じゃないの?
229 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 16:44:57 ] ファイル分割+テンプレートの特殊化で悩んでいます。 Test.h(Testクラス ヘッダファイル) Test.cpp(Testクラス コンストラクタ) show.cpp(Test<T>::show() 関数) show1.cpp(Test<Test<int>>::show() show()のテンプレート特殊化) で構成されています。 show.cppにあるTest<T>::show()を アップしたファイルのように書き換えるとコンパイルエラーが発生してしまい、 これを解決できません。 よろしくお願いします。 kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/7722.txt
230 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 17:58:13 ] Test.hのtemplate <typename T>class Testのメンバ関数として friend ostream &operator << (ostream &str, T const &val) { return str << val ; } C++はあまり使ったことはないけど、これでも追加するといいかも エロいひとの解答待つか
231 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 18:12:39 ] >>225 list だと、こうじゃなかったっけ? ごめん。調べないで書いてる。 for (list<C *>::iterator it = mylist.begin(); it != mylist.end();) { if ((*it)->ic == 1) { delete *it; mylist.erase(it++); } else { ++it; } }
232 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 18:37:02 ] erase したイテレータを++するのは未定義動作じゃなかったか?
233 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 18:45:29 ] >>232 mylist.erase(it++); はイテレータを進めてから、進める前のイテラータに対してeraseするから問題ないと思うよ。 listのeraseでは消したイテレータ以外は無効にならないから。
234 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 21:04:13 ] 戻り値が次の要素じゃなかったっけ? it = mylist.erase(it);
235 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 21:41:25 ] listなら++でも安全だとしても、別なコンテナに変えられる可能性も 考慮して、戻りを代入するべきでは。
236 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 22:10:33 ] >>235 set,multissetとかだとeraseの戻り値の型がvoidだったりするから、 it == hoge.eraseが書けないときもある。 vectorならeraseの戻り値を使えても、別なコンテナに変えられる可能性も 考慮してit++にするべきでは。
237 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 22:53:20 ] >>236 vectorならit++は使えない。
238 名前:229 [2008/09/14(日) 22:53:23 ] >>230 ありがとうございます。 <<のオーバーロードで修正がベスト何ですかね。
239 名前:デフォルトの名無しさん mailto:sage [2008/09/14(日) 23:26:15 ] vectorの場合remove_ifして得た新しい末尾以降をそれぞれdeleteした後にerase(new_end, end) とlistとはやりかたが違うから、差し替え考慮するのは無理があるんでない?
240 名前:デフォルトの名無しさん mailto:sage [2008/09/15(月) 02:15:17 ] vectorとdequeはeraseの後反復子が無効化されるので、eraseの戻り値が必要。 mapやsetはeraseの戻り値がvoidなので、it++するしかない。 シーケンスコンテナと連想コンテナの取り替えを想定するのは 無理があるって事だな。
241 名前:デフォルトの名無しさん mailto:sage [2008/09/15(月) 09:14:33 ] effective STL に同じような話がある
242 名前:デフォルトの名無しさん mailto:sage [2008/09/15(月) 10:28:05 ] Visual C++ 2008 Express Editionでコンパイルした実行ファイルを、VC++が入ってないPCではエラーが出て実行できないんですけど VC++が入ってないPCでも実行する方法を教えてください。
243 名前:207 mailto:sage [2008/09/15(月) 10:29:22 ] >>225 氏の方法でも >>231 氏の方法でもうまくいきました。 ありがとうございます。 「別なコンテナに変える」ということの意味はまだ良くわからないので、 引き続き勉強します。 >>241 > effective STL に同じような話がある なるほど、早速ポチりました。
244 名前:デフォルトの名無しさん mailto:sage [2008/09/15(月) 10:47:02 ] >>242 エラーが出ないように修正する
245 名前:デフォルトの名無しさん mailto:sage [2008/09/15(月) 10:53:17 ] >>244 VC++がインストールされているPCではエラーがなく実行できます。
246 名前:デフォルトの名無しさん mailto:sage [2008/09/15(月) 10:54:07 ] >>242 まずはエラーの内容を示さないと・・・・ MFC7のdllがないとかか。
247 名前:デフォルトの名無しさん mailto:sage [2008/09/15(月) 10:59:51 ] SideBySide絡みじゃ? MSから再配布可能なんちゃらを実行するPCにインストールすればいいとおも
248 名前:デフォルトの名無しさん mailto:sage [2008/09/15(月) 11:49:58 ] >>246 ほかのパソコンで実行すると指定したプログラムは実行できません。と表示されます。
249 名前:デフォルトの名無しさん mailto:sage [2008/09/15(月) 11:52:21 ] 何で初心者って「エラーが出ます」「うまくいきません」 「動きません」って言って具体的なこと書かないんだろうな。
250 名前:デフォルトの名無しさん mailto:sage [2008/09/15(月) 11:53:18 ] >>248 本当にメッセージそれだけ?
251 名前:デフォルトの名無しさん mailto:sage [2008/09/15(月) 11:57:28 ] >>250 今はほかのパソコンにもVC++を入れてしまっているので確認はできないんですけど、もう少し長かったような気がします。 VC++を入れてない人のパソコンでも何かインストールをしなくても普通のアプリケーションみたいに実行できるようにしたいんです。
252 名前:デフォルトの名無しさん mailto:sage [2008/09/15(月) 12:01:39 ] >>251 1. VC++のバージョンにあうランタイムライブラリをインストールさせる。 www.microsoft.com/downloads/details.aspx?FamilyID=9b2da534-3e03-4391-8a4d-074b9f2bc1bf&DisplayLang=ja www.microsoft.com/downloads/details.aspx?FamilyID=a5c84275-3b97-4ab7-a40d-3802b2af5fc2&DisplayLang=ja 2. msvcr90.dllなどをMicrosoft.VC90.CRT.manifestなどと共にEXEと同じフォルダに置く。