[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 2chのread.cgiへ]
Update time : 04/29 14:24 / Filesize : 158 KB / Number-of Response : 773
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

【C++】STL(Standard Template Library)相談室 10



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
コピー演算子をオーバーロード。






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<158KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef