1 名前:デフォルトの名無しさん mailto:sage [2008/08/26(火) 12:01:17 ] C++標準ライブラリの一つ、STLについて。 前スレ 【C++】STL(Standard Template Library)相談室 9 pc11.2ch.net/test/read.cgi/tech/1204045410/ 過去ログ・リンク・書籍紹介は >>2 以降
401 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 13:31:44 ] >>399 具体的にどこが危ないのか教えてよ 「使い方を間違えたら危ない」というレベルの話なら 「listen()を使う全てのプログラムは危ない」というのと同じになっちゃうから
402 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 13:39:40 ] >>401 え?最大文字数を指定できないじゃん それが危険だと思えないならまぁ好きにするといいよ
403 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 13:42:38 ] sprintfで100byteのバッファしか取っていないのに、 100文字以上有るかもしれないユーザ入力を与えるとかね。
404 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 13:44:11 ] VCのsprintf_s使ってます(^^)
405 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 13:46:22 ] ハア? char buff[100] sprintf(buff, "%.80s", user_input); これのどこが危ないって?
406 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 13:47:28 ] まさしく>>398 の最下行に書いてあるバカが言ってるとしか思えないんですけど。
407 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 13:48:08 ] C++ で何で sprintf なんて使ってるのん? しかも STL スレで・・・。 ostringstream か boost::format を使っとけ。
408 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:00:20 ] >>405 そういうことを分かって使う分にはいいけど、 実際に使う人間が必ずしも分かっているとは限らないし、 分かっていても、うっかりやってしまう危険性があるよね。
409 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:04:25 ] つうかそんな単純なケースならいいけど、 色々出力したりロケールが絡むと出力結果の予想がしんどいだろ
410 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:08:01 ] そんなレベルなら、「vectorで[]は使わないほうが良い。at()を使え。」と同じじゃないの。 特に>>399 はわざわざ>>398 に対して言ってるんだから もっとちゃんとした危険性を指摘してくれても良さそうなもんだけど。 そりゃ、切捨て前提という仕様は良くないとか 全部生かすつもりならsnprintfの方が楽だとか言うのはその通りだけど それとセキュリティ的な問題は全く別だから。 柔軟性だって例えば std::vecotr<char> buff; buff.resize(???); sprintf(&buff[0], "%.*s", buff.size()-1, str); のような使い方である程度確保できるし。 >>409 「使いやすさ」と「セキュリティ的に問題」は全く別の話なんですけど。
411 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:13:43 ] >>410 > 「使いやすさ」と「セキュリティ的に問題」は全く別の話なんですけど。 この一行が>>409 の話とは全く別の話なのは、そういうジョークなの?
412 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:14:33 ] ostreamが状態を持ってるのもしんどい
413 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:14:53 ] あ、別にユーザー文字列をそのまま配列に落とす場合に限らないよ。 そもそも(1箇所での)ユーザー入力なんて、普通は1つなんだから 例えば sprintf(filename, "file-%.80s%d.dat", input, num); のような形式でも、充分に最大値は予想できるし。 あ、「intが512bitの環境を考慮すると面倒」というのはその通りか。
414 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:17:55 ] 使い難さが有るということは、ミスり易いってことじゃね? ミスってもセキュリティ的な問題が出ないライブラリならいいんだけど。
415 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:19:43 ] いわゆる、バグというものは、ミスることによって起こるんだから。 十分予想出来るとかで大丈夫じゃないか、なんていい方出来るだったら、 世の中の全てのソフトウェアにはバグが無いってことも言えてしまう。
416 名前:409 mailto:sage [2008/11/09(日) 14:19:58 ] >>410 いやだから 出力結果の予想が困難→バッファ長の予想が困難 セキュリティ的にあぶなくね? という話し 気をつけて使え って話しなら そうですね としか言えないけど みなミスりがちだからsnprintfとかVC++のセキュア関数とか あるんじゃないの?
417 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:32:40 ] いやだから 全然>>398 への反論になってない。 「使い方を知らないのが問題」なだけでは 「セキュリティ的に問題がある」ということにはならないから。 まあ、416の言いたいことはもっともだし 他にもっと良い選択肢があるならそちらを使うべきなのは確か。 でも残念ながら標準ではない。 ただ、自分が「使い方を知らないバカ」だという自己紹介はもういいよ。 >>398 の最下行を無視して>>402 と反論するような人が>>399 みたいに書くわけだから。
418 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:35:28 ] あ、それと、「最大値の見積もりを間違える」点についてだけど 別に用意したバッファの95%以上まで使わなければいけない、というような決まりはないから。 多少(例えば末端の'\0'とか)の計算ミスがあっても充分すぎるように見積もって置けばよい。 例えば>>405 のようにね。
419 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:37:36 ] >多少(例えば末端の'\0'とか)の計算ミスがあっても充分すぎるように見積もって置けばよい。 ええええー
420 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:38:20 ] 最大量がきっちり分かってる状況じゃないかそれでいけるのは
421 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:41:24 ] は? 当然過ぎて困りますが ユーザー入力の部分の最大量は>>405 のように制限して その上で他の部分の見積もりが多少違っていても大丈夫なように ということですけど。
422 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:42:37 ] ユーザー入力の部分の最大値を制限するのは 当然というか大前提だと思っていましたが、皆さんは違うのですか。 認識の違いですね。
423 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:44:22 ] つまり、%fは使うなってことですね、判ります。
424 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:48:54 ] あー、sprintfは使い方が難しくセキュリティ的な問題を起こしやすいので使うべきではない。 とすると、 同じように、 使い方が難しくセキュリティ的な問題を起こしやすいものは使うべきではない ということになりますね。 つまり、 C++をやめましょう、と。 Javaあたりがよろしいでしょうか。 実際、世間の潮流もそういう流れになってますしね。
425 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:49:50 ] >>423 %.fを使ってください
426 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 14:52:52 ] >>425 sprintf(buf, "%10.0f", 1e100);
427 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 15:02:23 ] snprintf()なら、 snprintf(s, sizeof(s), … ってやっとけば安全だけど、 sprintf()は人間が数えないといけないじゃん。 >>405 見たいな単純なやつだったらどっちでもいいってことになるかもしれんけど、 書式が複雑になってくると、ミスる可能性がでてくるよ。 てか単純にsnprintf()のほうが楽ジャン。sprintf()で人間がバッファサイズ数えるなんて非合理。
428 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 15:04:36 ] いつまで STL スレで sprintf の話をやってんだよ。 そんな型安全じゃない C の糞遺物なんぞ C++ で使うな。
429 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 15:05:04 ] だよな!
430 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 15:07:32 ] >>426 printf("%.2u", -1); の時に必ず2桁に収まると思う人は居ませんね。 これと同様に最大桁数が見積もれる点は変わらないと思いますが。 いや、最大桁数はbit数に依存するので環境依存ですけど。 >>427 だからsnprintfはC++においては非標準だって。 それに「sprintfはセキュリティ的に問題がある」という意味にはならないよ。 「C++はセキュリティ的に問題がある」というのと同様。
431 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 15:07:47 ] ところで型安全って何ですか?
432 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 15:10:57 ] snprintfってC99からなんだっけ… 0xでは標準になるのかなぁ
433 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 15:12:10 ] なりません
434 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 15:13:40 ] 相変わらず話題の質が下がると賑わうな。
435 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 15:20:11 ] >>432 ドラフト N2798 の 17.1 [library.general] p9 より > This library also makes available the facilities of the C99 standard library, > suitably adjusted to ensure static type safety.
436 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 15:23:46 ] _scprintfで数えたらいい
437 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 15:28:25 ] >>430 doubleの最大桁数を常に見込んでバッファを確保するとでも? %fを使わずに、素直に%gを使えば済むじゃん。 そういう使いこなしを必要とするからsprintf()は難しいと言うなら判るが、 使いこなしてもいないのに語ろうとするな。
438 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 15:33:24 ] 結論:ostrstream or boost::lexical_cast or boost::format or boost::egg::to_string
439 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 16:00:48 ] 結論:いままで聞いた話を総合すると、一番スマートなのはこれ。 std::string str; int a = 123; str.resize(12); sprintf_s((char*)str.c_str(), str.size()-1, "%d", a); str.resize(str.find('\0')); ストリームとかで中間バッファを使うのはメモリの無駄だし、sprintfの書式指定能力の高さは最強。
440 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 16:02:21 ] >>439 その場合だとstr.size()は0が返るよ。 あと規格は大切にね。
441 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 16:03:16 ] >>その場合だとstr.size()は0が返るよ。 ごめん勘違いした。 でもその書き方は受け入れられない。
442 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 16:05:42 ] c_str()を出力バッファに使う男の人って
443 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 16:06:48 ] もはやSTLじゃねーなw
444 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 16:13:28 ] vectorを使えばかろうじてSTLに関する話題の範疇に入…らないか
445 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 16:17:17 ] >>439 × (char*)str.c_str() ○ &str[0] あと、せっかくだから sprintf_s() の戻り値使えよ。
446 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 16:30:07 ] >>445 規格ではstd::stringのメモリ上の連続性は保証されていない。 std::vectorと混同するな
447 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 16:33:39 ] どうせ大丈夫なんだから別に良いじゃん
448 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 16:35:47 ] 仕事で一緒にならないなら別にいいよ
449 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 16:38:17 ] >>446 C++0x で連続性は保証されるようになるし、 現状のどの実装でも連続性は成り立っている。
450 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 16:41:45 ] >>446 www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530 まぁ現時点で保証が無いというのは確かなんだけどね。
451 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 17:38:58 ] size_t count = _sctprintf(_T("%d"), 777) + 1; std::vector<TCHAR> buffer(count); _stprintf_s(&buffer[0], count, _T("%d"), 777);
452 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 17:52:09 ] TCHAR(笑)
453 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 18:42:07 ] >>449 そういう話をしたいのなら実装依存スレへ逝け
454 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 18:43:16 ] >>451 そういう話をしたいのなら実装依存スレへ逝け
455 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 19:54:23 ] STLのlistを利用したプログラムを実行中、 "list iterators incompatible" という例外が発生しました。これはどういったエラーでしょうか? 開発環境はVisualStudio2005 AcademicEditionです。
456 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 20:01:13 ] ソース晒せ
457 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 20:06:15 ] transformの使い方に関して質問があります。環境はGCCです。 目的は、stringの中身をすべて小文字に変換したいのです。 #include <string> #include <algorithm> #include <cctype> #include <cstdio> #include <iostream> string aa = "AbCdEfG"; transform(aa.begin(),aa.end(),aa.begin(),tolower) で、aaの中身をすべて小文字に変換できません。 理由はわかりますでしょうか?
458 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 20:10:50 ] >>457 とりあえずコンパイルエラーだろ。 エラーの意味がわからんということならエラーメッセージ晒せ。
459 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 20:14:20 ] 俺の環境では全部小文字になるが・・・。
460 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 20:20:44 ] 使用したソース #include <string> #include <algorithm> #include <cctype> #include <cstdio> #include <iostream> using namespace std; int main(){ string aa = "AbCdEfG"; transform(aa.begin(),aa.end(),aa.begin(),tolower); } 以下がコンパイルエラー test.cpp: In function 'int main()': test.cpp:9: error: no matching function for call to 'transform(__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits\ <char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> \ > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, <unresolved overloaded f\ unction type>)' よろしくどうぞおねがいします。
461 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 20:23:26 ] >456 ttp://www.hsjp.net/upload/src/up51891.txt 本来の拡張子は.hppです。ごちゃごちゃしててすみません。 103行目のupdate_etc()関数が怪しいと思っているのですが…
462 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 20:24:53 ] Effective STL に乗ってたネタかな
463 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 20:32:13 ] >>457 たぶん、こういう関数オブジェクトを作ってそれを渡せばいいよ。 struct my_tolower : std::unary_function<char, char> { char operator ()(char c) const { return std::tolower(c); } };
464 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 20:54:01 ] transform(aa.begin(), aa.end(), aa.begin(), static_cast<int(*)(int)>(tolower)); 通った typeof(aa)::value_type : char tolower : int(*)(int) でtolowerをchar(*)(char)と型推論しようとして失敗してる なので正確にキャストして与えてやればおk?
465 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 20:57:12 ] >>461 まずはデバッガのバックトレースを見たりブレークポイントつかったりしてあたりつければいいよ segvだろうが、unhandled exceptionだろうがどこで発生したか分かるから
466 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 21:00:18 ] >>464 >>460 の最後の行の中にunresolved overloaded function typeってのがあるでしょ。 C++では、tolowerが多重定義されているのだが、 それではテンプレート引数の型が決定できないということでエラーになる。 だから、>>464 のようにキャストが必要になる。>>463 みたいに他の方法も考えられる。
467 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 21:06:27 ] >>466 >>464 >>460 ありがとうございます。 なるほどよく分かりました!
468 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 21:21:38 ] >465 ありがとうございます。とりあえずどこで投げてるのか絞り込んでみます。 ただ、list iterators incompatibleというのがどういう状態を指すのか、よくわからないのです。
469 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 21:37:51 ] vcのstlのincludeディレクトリにて"list iterators incompatible"で全文検索するとか
470 名前:デフォルトの名無しさん mailto:sage [2008/11/09(日) 22:01:54 ] >469 そういう方法もあるのですね listの中を覗いてみます。 ありがとうございます
471 名前:デフォルトの名無しさん mailto:sage [2008/11/12(水) 11:38:03 ] dequeにpush_backで要素を挿入していくのは、予め配列をサイズ決め打ちで宣言して代入していくのより遅いですか?
472 名前:デフォルトの名無しさん mailto:sage [2008/11/12(水) 12:13:18 ] >>471 速度は実測が基本。 一般的に、 push_back() を繰り返す場合、配列要素のメモリ確保回数が増えるので 遅くなる可能性が高くて、それでも push_back() ならコピーコンストラクタが使われるので 要素の型によっては代入に比べて速い可能性もある。
473 名前:デフォルトの名無しさん mailto:sage [2008/11/12(水) 20:00:12 ] 気になるけど図るのが面倒臭いなら、reserveしておけば精神的に気が和らぐ。
474 名前:デフォルトの名無しさん mailto:sage [2008/11/12(水) 22:12:15 ] vectorならreserveは必須だと思う dequeってどうだろう
475 名前:デフォルトの名無しさん mailto:sage [2008/11/12(水) 22:21:59 ] dequeはある一定の長さのブロックが不連続に確保されるそうだから reserveしたらシステムからメモリを持ってくる時間は稼げるけどvector と違ってメモリの再配置は起きにくいんだよね
476 名前:デフォルトの名無しさん mailto:sage [2008/11/12(水) 23:24:27 ] それは実装によるんでは。
477 名前:デフォルトの名無しさん mailto:sage [2008/11/12(水) 23:32:37 ] 実装によるのはもちろんだが一般的な実装の話ね
478 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 01:13:27 ] dequeのpush_backが(償却じゃなくて正真正銘の)定数時間であることは規格で要求されてたはず だから一概に実装に依るとも言えない
479 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 07:48:57 ] dequeはpush_back/push_frontで既存要素のコピーが起こりえないのがありがたい まあ最初から要素数が判ってるならvector一択だけど
480 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 20:37:08 ] STLのことは良く分からないけど、 list,stack,queue,vector,dequeで空のクラスSampleのポインタを、 10万個格納、(1個delete&削除・1個格納)*10万回、 空になるまでdelete&要素削除 してみた。 vectorは予め追加要素の2倍reserve()した。 要素の追加削除はvector,stack以外『古い物から削除』、前から取り出して後ろから追加でやった。 stack、queueはそれぞれコンテナdequeを利用。 list 68.11 秒 vector 20.344 秒 stack 27.5 秒 deque 9.468 秒 queue 9.438 秒 queueが速すぎてワロタ dequeは操作する方向次第でstackとほぼ同等 queue,stack,dequeはこの場合、実質同じモノだし queue,stackのコンテナを変えたら悲惨な結果になった PCが悲鳴を上げたのでこれ以上のテスト回数は勘弁
481 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 20:41:18 ] あぁ、次はboost::circular_bufferだ…
482 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 20:58:12 ] >481 >480と同条件、上限20万個として計測してみた。 平均5.5秒くらいだった
483 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 23:21:57 ] ひょっとしてlistってあんまり使わない方が良い?
484 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 23:51:07 ] むしろ連結リストのくせに良い数字が出てると思うがね
485 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 00:18:06 ] リンクリストより配列のほうがキャッシュに引っかかりやすいからいいぞってMSも言いている。 msdn.microsoft.com/ja-jp/library/eye126ky.aspx
486 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 00:33:54 ] >>483 状況次第 listのほうが向いてる使い方もあるしね
487 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 00:54:30 ] 途中(先頭末尾以外)の要素の削除はlistじゃないとやってられんやろー
488 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 00:55:31 ] あとリストの連結やリストの分割もあるか あれ?そんなことできたっけ・・・?
489 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 01:01:03 ] とりあえずただデータを突っ込んで置きたい(出し入れ順番とかどうでも良い)場合には、 リストは不向きってことか
490 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 01:14:52 ] 昔はやたらとリンクリストを使うのがいいとされていたが、 今のご時世でも初心者にリンクリストを教えたがる間抜けが後を絶たない。 普通にstd::vectorを使えるように仕込んでおけば、std::listを使うのも苦労はないだろうに。
491 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 01:15:39 ] >>487 途中の削除もdequeは結構速い。 listは削除してもイテレータが無効にならないのが利点かな。
492 名前:1/2 mailto:sage [2008/11/14(金) 15:46:52 ] listを使っていてよく分からない事態に遭遇したので質問します。 長くなってしまったので申し訳ありませんが分割投稿します。 環境:VC++2005 / XP typedef struct globalArray { int type; char name[100]; float variable[5][5]; } globalVar; typedef struct nodeDat { CShaderNode *nodeKind; globalVar varDat[5]; // 上の構造体(globalVar) int dataNum; float power; } nodeData; typedef struct _data { nodeData mainNode; // 上の構造体(nodeData) nodeData blendNode; // 上の構造体(nodeData) nodeData subNode; // 上の構造体(nodeData) int materialNum; dxMaterial *matrials[MAX_MATNUMBER]; } dataBlock;
493 名前:2/2 mailto:sage [2008/11/14(金) 15:47:25 ] 上のような構造体が有りまして、一番下のdataBlockをリストとして扱っているのですが、 dataBlock tmp; /* 〜 データ作成処理 〜 */ /* 〜 挿入先探索 〜 */ insert(itr,tmp); とデータを挿入してリストを覗くと途中までしか正しくデータが入っていません。 データ作成過程で"",NULL,0.0fと全て初期値を用いてデータを初期化しているのですが、 data[0]->mainNode.varDat[0].variable 以降のデータが未初期化のまま生成されています。 構造体を入れ子にする前は正しく動いていたのですが、 listを扱う際は構造体を入れ子で扱うとNG等の制約があるのでしょうか。 ご教授お願いいたします。
494 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 15:53:19 ] それだけだと推測しかできん ・初期化の部分が不完全か ・未初期化というのが勘違いか ・リスト操作がバグってるか のいずれかしかないが、心当たりがないなら何か見逃してるんだろう そのようなNG的制約は無いので大丈夫
495 名前:492 mailto:sage [2008/11/14(金) 16:04:13 ] 返信ありがとう御座います。 (※(int)はキャストではなく型を説明上明示するために便宜的につけた物です。紛らわしくてすみません。) 例えば仮データ(tmp)で、 (int)materialNumを0で初期化したのがリストのデータでは (int)materialNumが-33686019になってしまっているので、 >・リスト操作がバグってる のでしょうかね…… ありがとうございます。制約は無いときいて安心しました。 もう少し追ってみます。
496 名前:492 mailto:sage [2008/11/14(金) 16:30:43 ] 連投失礼いたします。 色々弄ってみたところ、構造体のメンバの記述順を入れ替えると正確に入るデータと入らないデータが出てきました。 詳しく調べたところ、連結しようとしている構造体は180byteで、リストで正しく入るのは96byteの領域まででした。 数字的にこれって多分仕様ですよねぇ……
497 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 18:55:54 ] -33686019ってことは0xfdだろ? ちゃんとdeep-copyせんと。
498 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 19:59:55 ] dataBlock tmpA; /* 〜 データ作成処理 〜 */ dataBlock tmpB; tmpB = tmpA; ってやって、tmpAとtmpBは同じ内容の独立したオブジェクトになる?
499 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 20:04:28 ] 誰にもわかりません
500 名前:492 mailto:sage [2008/11/14(金) 21:01:27 ] 返信ありがとう御座います。 >>498 さんのを実行してみたところ、同内容の独立したオブジェクトに成りました。 deep-copyなのですが、 /* 〜データ作成処理〜 */ を抜けた後、tmpに全ての値がきちんと入っていることを確認し、 data.insert(itr,tmp); でインサートを行っているのですがコピーに関してはlist側で処理されている様で、 こちら側からコピー処理を定義することが出来るのでしょうか。
501 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 21:50:22 ] >>500 コピー演算子をオーバーロード。