C++相談室 part133
■ このスレッドは過去ログ倉庫に格納されています
次スレを立てる時は本文の1行目に以下を追加して下さい !extend:on:vvvvv:1000:512 C++に関する質問やら話題やらはこちらへどうぞ。 ただし質問の前にはFAQに一通り目を通してください。 IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。 前スレ C++相談室 part132 http://mevius.5ch.net/test/read.cgi/tech/1507561894/ このスレもよろしくね。 【初心者歓迎】C/C++室 Ver.102【環境依存OK】 http://mevius.5ch.net/test/read.cgi/tech/1509780815/ ■長いソースを貼るときはここへ。■ http://codepad.org/ https://ideone.com/ [C++ FAQ] https://isocpp.org/wiki/faq/ http://www.bohyoh.com/CandCPP/FAQ/ (日本語) VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured 今だとC++でGUIやるならQtがデファクトだと思うからそっちの方がいいんじゃない? GTK使えと命令されてる立場ならすまん Qtとかでかいしライセンスは高いし謎の独自拡張を使わされるわでかなり使いにくいんだが そのくせ特別使いやすいわけではない でもネットや本の情報は多そうじゃない? まあ用途も聞かずに頭ごなしに勧めるもんではなかったなすまんかった io2dまだかー。 ウニファイドコールシンタックス復活せよ〜。 基本的な動作について知りたい msgrcvは、msgsndされた瞬間にキューがたまるから、キューが追加されたと同時に待機状態をやめて動き出す これであってる?? あと、msgsndする先やmsgrcvで確認する先はmsggetで動的に確保された番号を知らないといけない こうであってるかな? システムコールの話ならLinux板にでも行け なんかのライブラリの話なら知ったこっちゃないわ これ実行すると0と2が表示されるので一応は問題ないですか?汚いとは思うけど。 int main(void) { vector<int> vec; vec.push_back(0); vec.push_back(1); vec.push_back(2); for(vector<int>::iterator ite = vec.begin(); ite != vec.end();){ if(*ite == 1){ vec.erase(ite++); printf("num: %d\n", *ite); }else{ printf("num: %d\n", *ite); ++ite; } } return 0; } >>624 >vec.erase(ite++); ite = vec.erase(ite); にすべし あと、次の行のprintfは削除で おっと、質問は問題あるかどうかだった。 結論から言うと、問題はある。 0〜2までではなく0〜3までvectorに入れてから実行すれば、 まともに動作していないのは分かるはず。 >>626 やっぱこうしないとダメですね。 ite = vec.erase(ite); どうもでした。 一応はこれでもいけるってことですかね?削除した時は次の要素になるという理解でいいですか? for(vector<int>::iterator ite = vec.begin(); ite != vec.end();){ if(*ite == 1){ vec.erase(ite); }else{ ++ite; } } これlistとvectorでも違いました。 listだと++しないと正常に動作せず for(list<int>::iterator ite = lst.begin(); ite != lst.end();){ lst.erase(ite++); } vectorだと++すると上手く動作しない for(vector<int>::iterator ite = vec.begin(); ite != vec.end();){ vec.erase(ite); } でもeraseの戻り値取得するのが一番いいですね。 std::vector::eraseのリファレンスに、こう書いてある。 https://cpprefjp.github.io/reference/vector/erase.html 削除された要素またはそれ以降の要素を指すイテレータや参照は無効になる。 これによると、vec.erase(ite); 実行後にはiteが無効になることになる。 あなたの環境だと、たまたまiteが削除した次の要素になったのかもしれないが、 それがすべての環境で成り立つ保証はない。 >>631 基本的にはvectorは無効になるということですかね。 >>631 そのinvalidationは既に取得してるiteratorに起こるやつでは? >>631 なんか変な説明だね vector<int> vec{0, 1, 2}; auto ite = vec.begin(); ++ite; vec.erase(ite); --ite; cout << *ite; //これでvec[0]にアクセスできそうに聞こえる 内容的にはこういうことなのに vec.m_head = realloc(vec.m_head, 2 * sizeof(int)); listだとこれで動くと思っていいのかな for(list<int>::iterator ite = lst.begin(); ite != lst.end();){ lst.erase(ite++); } >>634 eraseした時点で削除された要素のitrも無効だから--できないと思うけど、 別途確保しておいたitrは有効であるかのように読めるから、確かにおかしいね >>635 どうやら合法。 そもそもこれ何してんの? 表示とともに要素を消したいならFILOなコンテナ使いなよ std::stackみたいな >>636 listはOKそうですか。 >>637 いやとくに意味はないです。ただvectorとlistで動きが違ったので気になりました。 アホか eraseの戻り値が何のためにあると思ってるんだ >>639 eraseの戻り値使うのが一番いいのは分かったんですが 単にvectorとlistで動作が違うのが気になっただけです。 vector だと要素の再配置が必要になるけど list はそうじゃないって話 https://gabekore.org/vscode-c-windows ↑のサイトを見ながらCの開発環境を作っているのですがCの当たりから分からなくなってしまいました‥‥ 説明のユーザー設定というものがそもそも無かったです‥‥ただの設定を開いたらこの画面になったのですが、この右に書いたのは合ってるのでしょうか‥‥? このあとのDからはほんとによく分からなくなってしまいました‥‥この程度が出来ないなら、プログラミングなんて出来ないですよね‥‥(..;) 自分が不甲斐ないです‥‥-_- https://i.imgur.com/VH9Yt5X.jpg >>642 MacでもLinuxでも使えるVisual Studio Code Part2 [無断転載禁止]©2ch.net http://mevius.5ch.net/test/read.cgi/tech/1494638671/ 削除する場合とそうでない場合の処理を分ければOK forでもwhileでもOK リストでもOK std::vector<int> vec{ 0, 1, 2 }; auto it = vec.begin(); while (it != vec.end()) { if (*it == 1) it = vec.erase(it); else it++; } for (auto n : vec) { printf("vec %d\n", n); } std::list<int> list{ 0, 1, 2 }; auto it2 = list.begin(); while (it2 != list.end()) { if (*it2 == 1) it2 = list.erase(it2); else it2++; } for (auto n : list) { printf("list %d\n", n); } >>640 根本的に勘違いしていると思うけどな。 × > eraseの戻り値使うのが一番いいのは分かったんですが ○ eraseの戻り値を使わなければならない(そうしないと意味がない) × > 単にvectorとlistで動作が違うのが気になっただけです。 ○ 戻り値を使えば同じソースコードになるように設計されている 何の為にイテレータを使うか分かっておらず、 イテレータ使えば効率が上がると勘違いしているJava鹿程度の知能なんだろ。 Linusが文句言っているのもこういう連中に対してなんだが。 javaとかc#はイテレータで列挙してる最中に要素を削除できない 例外になる C++ 使っててもLinusに馬鹿にされてるぞ C原理主義者(OSつくってるひとたち)はC++を馬鹿にして C++信者はCを馬鹿にする 滑稽だな >>634 規格書の文言そのままの説明だと思う。 vec.erase(ite)の段階でiteは無効になるのでそれ以降は未定義だからvec[0]にアクセスできる保証はないという意味になる。 vector::eraseで領域の再確保は発生しないので削除する要素以前のiteratorは無効にならない。 vectorのiteratorをポインタで実装していれば次の要素をさしてそうなものだけど、そうでない実装、例えば削除した分だけ自動的にずらして同じ内容を指し続けてくれたり、例外を投げて間違いを知らせてくれるとかがありうる? eraseの戻り値がなぜ必要かが分からないなら、vectorとiteratorの実装コード見て理解したらいいよ。 というか特定の値を消したかったらremove_if使おうぜ c++についての質問です。 call by reference あるいは call by value にて引数の受け渡しを行う関数を利用して、乱数発生ルーチンを評価し、評価得点法による最適次数n(<5)を求める場合どのようなプログラミングになるのでしょうか? 教えてください。よろしくお願いします。 ここまではできたんですが、このあとどうすればいいでしょうか? https://i.imgur.com/XmuQ0Mw.jpg >>651 「乱数の評価得点表」「最適次数」とはどういう概念ですか? 適切な資料を教えてください。 >>646 まあその実装の方が初心者向けには妥当だな。 C#はそこら辺の「割とどうでもいいが無駄に複雑になる」部分を回避していていいと思う。 ただまあ、この方向(堅牢性、容易さ)のベストは実行時例外ではなくコンパイルエラーであり、 C#もまだそこまでは行けてない、ということだね。 なおJavaScriptはその辺保証してない。「出来るだけ止めない」方針だからね。 > もしプロパティがある反復で修正された後に訪問されたなら、ループにより公開される値は後の時点での値となります。 > 訪問される前に削除されたプロパティは、それから後には訪問されません。 > オブジェクトに対する反復が起きている中でそのオブジェクトに追加されたプロパティは、訪問されるかもしれませんし反復から省略されるかもしれません。 > https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for...in >>647 Linusが馬鹿にしているのは、意味もなく抽象化して喜んでいる馬鹿C++erだろ。 正しく抽象化している分には馬鹿にして無いと思うが。 とはいえ、OS組むならC++よりもCなのは事実だよ。 >>648 >>631 を理解できない馬鹿共は放置として、君の理解にも多分間違いがある。 > ありうる? 多分無い。 × vec.erase(ite)の段階でiteは無効になるのでそれ以降は未定義だから ○ vec.erase(ite)後にiteが指すのは「次の要素」であり、 元々指していた「削除された要素」ではないことを「無効」と表現している。 そしてそれ以前に「削除された要素」以降を指していた物も全部ずれるので、 「削除された要素またはそれ以降の要素を指すイテレータや参照は無効になる。」という表現になる。 つまり、この文字数であればきわめて妥当な表現であり、ゆとりが馬鹿すぎて理解できないだけ。 > vectorはシーケンスコンテナの一種で、各要素は線形に、順序を保ったまま格納される。 > https://cpprefjp.github.io/reference/vector.html つまり、ド頭から密に詰められていることを規定されているので、 削除すれば当然次の要素が入るに決まっているし、 (これは君は正しく理解しているが)reallocはなされないし、 vec[0]についてもアクセス時点での先頭要素が取得できるに決まっている。←多分君はここを勘違いしている c原理主義者はそぎ落とされたロジックにしか興味ない c++は彼らにとっては冗長なんだろう GNUのツールセットのコードをみてると納得いく しばらく見てると脳のワーキングメモリが不足しておかしくなりそうだ が、残念なことにifとフラグとマクロ使いまくりの糞コードにも見える >>656 オススメのツール(ソース)ある?見てみるから。 URLあれば助かる。 そこら辺は古すぎるので現在の常識とは異なる場合があると思うけど std::vector::erase - cppreference.com http://en.cppreference.com/w/cpp/container/vector/erase >Invalidates iterators and references at or after the point of the erase, including the end() iterator. 翻訳には肝心のモンが抜けてるんじゃあねえのか? 複数形のsとか >>659 サンクス。見てみているが、まずGNUはこのコーディングルールがな… ちなみにこれ、今時ハイライト(色づけ)されないのは何とかならないのかね。 http://git.savannah.gnu.org/cgit/grep.git/tree/src/grep.c >>660 そう思うなら、今の常識に照らして書き直してあげたら? パフォーマンスあがるならマージしてもらえるぞ Linusはプログラマの頂点ではないしGNUは最も優れたプロジェクトではない 既に手本にならない部分は多い >>655 >元々指していた「削除された要素」ではないことを「無効」と表現している。 そうなの? 規格ではclearとかresizeとかでも無効になる(invalidate)と書いてあるしeraseがそれと何か違うようにも見えないし、無効なiteratorをdereferenceするのは未定義だとも書いてあるように見えるけど。 >つまり、ド頭から密に詰められていることを規定されているので、 >削除すれば当然次の要素が入るに決まっているし、 >(これは君は正しく理解しているが)reallocはなされないし、 >vec[0]についてもアクセス時点での先頭要素が取得できるに決まっている。←多分君はここを勘違いしている ポインタならそうだろうけどvectorのiteratorでも規格上保証されてるの? ttps://stackoverflow.com/questions/45758659/does-stdvectorerase-really-invalidate-the-iterator-at-the-point-of-erase >>661 > including the end() iterator. いや、これが抜けてる方が大問題だろ。 まあ広い意味では「それ以降の要素を指すイテレータ」に含まれるとも言えなくもないが、 これについては明記されるべきだね。 しかしこれだとイテレート中に削除していいのか?と心配になるが、 直ぐ下のサンプルコードで「偶数番目の要素を削除」してるからいけるんだろうね。 てか初心者なら、この辺のサンプルコードから出発した方がいいよ。いろんな意味で。 ちゃんと公式な使い方してあるし。(当然戻り値をイテレータに代入している) > // Erase all even numbers (C++11 and later) > for (auto it = c.begin(); it != c.end(); ) { > if (*it % 2 == 0) { > it = c.erase(it); > } else { > ++it; > } > } > http://en.cppreference.com/w/cpp/container/vector/erase >>663 何で興味もないものに時間をかけてやらなきゃならない ちゃんと動いていれば十分 std::vector の場合はこう、std::list の場合はこう、とかいう知識はあまり意味がないのではないか? erace() したら、erace() したところおよびその後を指していたイテレータ(=ポインタ)は使えなくなる、くらいで一括するのが妥当だと考える。 細かい場合分けするのはプログラミング的に悪だと思ってる。 統合的に丸っと処理できると気持ちいい。 なのでちょっと粒度を上げてSTLの作法というものを考えた方がイイ。 >>665 つか、君は何に文句を言っているのだ?そこにそのまま書いてあるだろ。 > When describing iterator invalidation, > the C++ standard takes the simplifying assumption that iterators refer to elements, > and a valid iterator value always refers to same element. > Invalidating references, pointers or iterators to an element all follow the same rules. (The exception is the end iterator). > > Clearly references or pointers to the erased element are invalidated by a call to erase, > thus under the standard's simple rules so are all iterators. > It could have described what new element must be moved in place abd substituted what iterators refer to, > but the writers of the standard chise not to go there. They instead simply dictated the iterator was invalid. eraseでvecが移動しないことは保証されてるだろ。 当然vec[0]は削除後の先頭要素を指す。 ただしそもそも削除後にイテレータを再代入してないコートについては知るかボケだろ。 それについてもそこにモロに書いてあるし。 そのページは俺の言い分を全く書いてあるような物なんだが、何が言いたいんだ? そもそもeraseするならvectorなんか使うな。よっぽど小さいvectorじゃない限り eraseは縮小操作だからリアロケーションは起きないけどその時何が起こるのか理解してるのか? 理解できないならお前はC++を使えないやつ >>659 こんなもんじゃね?みたいな感じなんだが。 決して理解したわけではなく、雰囲気だけしか見てないが。 C特有のstructの嵐でもなく、 今ならIDEが警告出してくるほどのif文等のネストもなく、 意味不明なマ黒魔術使いまくりでもない。 グローバルが嵐になっているが、これはCUIツールだから大して問題ないし。 色が付いてないのとコーディングルールがアレなので詳しく読む気にならないが、 整形ツール通せば結構読めるコードのような気がする。 >>671 >eraseでvecが移動しないことは保証されてるだろ。 >当然vec[0]は削除後の先頭要素を指す。 誰もそんなことは問題にもしてないんだが大丈夫? 偉そうなことを言ってる割には全然読めてないんだなあ >>675 >>634 から読み直してこい。俺も言葉を省略したが文脈上まさか読み間違う人がいるとは思わなかったんだ。 >>634 ite = vec.begin() ++ite; ite = vec.erase(ite); --ite; であれば ite == vec.begin(); は保障できるが、 vec.erase(ite) とした場合の ite の値は、コンテナ vec のどこかを指している保障はないのでは? したがって、--ite もどこを指しているか保障がないのでは? 典拠を示してほしい イテレータを削除したときあり得る処置。 一個目。 メモリの再確保相当のことをして再構築する。 二個目。 尻尾の要素をムーブして詰めて最後の要素を開ける。 このどっちかだと思う。 2個目だとイテレータのロストはしないかもしれないが、 1個目だとアドレスが変わっちゃうのでイテレータが保持しているアドレスは無効。 両方あり得るのでeraseの戻り値はちゃんと受け取ろう。 >>680 お前もちゃんと読めよ > 戻り値 > 削除された要素の次の要素を指すイテレータを返す。 > そのような要素が存在しない場合は、end()を返す。 > さらに、削除された要素以降の要素の数と同じ回数のTのムーブ代入演算子が呼ばれる。 > https://cpprefjp.github.io/reference/vector/erase.html つかC++にはGCねえんだよ Java鹿死ね 規格にきっちりかっちり書いてある挙動について あり得る処置(キリッ とか抜かして適当な憶測垂れ流す奴がいるんだな なんか話が混ざってる気がするけど、eraseに渡した引数のイテレータの話じゃないの? >>681 >○ vec.erase(ite)後にiteが指すのは「次の要素」であり、 >元々指していた「削除された要素」ではないことを「無効」と表現している。 とか書いちゃう人が言っても説得力ないけどねw >>681 GCどっから出てきた。韓国人といい。話が飛躍しすぎ。 昔のvectorは同一メモリ上にデータが配置されていることは保障されていなかったから昔の環境でなにか作る場合は注意したほうがいい。 そういう処理系が存在するのかどうか疑問だけど。 >>679 俺の論旨は保証ねえだろなんだが だからreallocを持ち出した 典拠というのがあるなら631で 俺はそれを変だと言っている >>687 え?? 昔ってどのくらいのことを言っている? そもそも連続領域でなければリストと同じ特性になってしまい 配列であることのメリットが完全に失われるだろ ポインタの配列になっていて実体はばらばらでもよいということならわかるが >>649 横だが。 ソース見ろとよく言っている奴が居るので偶には、ってやってるんだが、 どこにあるかわかりにくい上に何だかなあ、なコードなんだが。 とりあえずこれでいいのか? https://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a01116_source.html そしてiterator.cがどこにあるか分からないという、、、 同様の奴もいるが、あまりオススメはされてない。 https://stackoverflow.com/questions/4304783/c-vector-source-code > 00402 iterator > 00403 erase(iterator __position) > 00404 { > 00405 typename _Base::iterator __res = _Base::erase(__position.base()); > 00406 return iterator(__res, this); > 00407 } > 上側URL __position.base()ってのは<T>だから致し方なしかもしれんが、 確かにこれだとC使いにとってはC++は冗長すぎる。 > c原理主義者はそぎ落とされたロジックにしか興味ない > c++は彼らにとっては冗長なんだろう (>>656 ) は当たってる。 >>689 C++は厳密な定義を始めたのはここ最近の話で昔はほぼ実装に丸投げしてた。 これは、きゃするのように仮想コンピュータを定義しないでやってきたツケだな。 ぼんやりとコンピュータっていうものの抽象化イメージだけで進んできた。 あと、C++はわからないけど、Cはとあるコンピュータに依存するものは規格に入れない決まりになってたと思う。 >>691 韓国人2号も死ね つかお前は>>682 が>>680 (お前)向けであることをまず理解しろ 日本語が不自由なら死ね この手のキチガイが湧いてくるまでになったか このスレももう終わりだな 流れ読んでないけどvec[0]が無効になるって発言したやつがいるから荒れてるの? 真に受けてソース読んでるしw というか読めてないしwww 実装見ても理由なんて分かるわけないだろ 質問者の使ってる実装は動いてしまう実装なんだから >>694 誰もそんなこと言ってないけどそう言ったと勘違いした人はいたみたいね 荒れてる原因はみんなが少しずつテキトーなことを言ってるからじゃないか? >>692 俺が死んだら責任とってくれるんだよね? 遺書を書いて死んだら>>692 は事情聴取くらいはされるかもね このスレ頭おかしいのとプログラミングスキルでイキリ散らしたいのしかいねえな 俺は叩き合いが面倒だから理由つけてしゃべってるのに、問答無用で死ねはひどいよなぁ。 完璧超人じゃないから間違いの一つや二つくらいするよ。 なぁ。完璧超人。鏡見てみたらいいと思うよ。自分ぶっ殺したくなると思うよ。 > プログラミングスキルでイキリ散らしたい ニヤニヤ 文献に書いてあることが全てだと真信してマニュアル通りに事を進めていくってまぁ受験とかならソレで良いかもしれないけどね。 物事の成り立ちを追っていくと決してその通りではないことも世の中にあるわけできちんとそういう所は汲み取っていかないとただ の鉄砲玉みたいな一番扱いが厄介な「無能な働き者」になってしまうよ。 特にこの業界では型にはまってばかりの柔軟性のない>>692 みたいな思想の違うものは徹底的に粛清しようとするワンマン堅物野郎は淘汰されるべきだと思うけどね。 >>694 日本語も英語も読めない不遜鮮人2人(>>674 ,>>686 )が火病してるだけ。 話に脈略が無く、突然火病るのはいつものこと。 だから嫌われる。当然韓国人は排除されるべき。邪魔だから。 話が噛み合ってないのなら噛み合わせる努力をすればいいだけ。 それ以前に知りもしない奴がデタラメに回答する必要もない。 そして状況を知りたければ全部読めばいいだけ。 日本語が読めない馬鹿ゆとり>>694 も邪魔なだけ。 つまり、結論は、 韓国人マジで死ね ゆとりも死ね お前らが居なければどれだけ2chから雑音が減るか、少しは考えてみろ。 初心者ですがGC付きの言語しかやったことないのでメモリ管理について質問させてください 例えば下記のようなコードでは、hoge関数で確保したvector用のメモリはGCがないためプログラムが終了するまで解放されないということでしょうか? 少なくともpiyo関数が終了するまでは残ってないと使えないですよね? vector<string> hoge(){ vector<string> v = {"hoge", "piyo"}; return v; } string piyo(){ vector<string> v2 = hoge(); string s = v2[0] + v2[1]; return s; } int main(){ cout << piyo(); } まずはスタックとヒープをググって調べてみるといいかも。 >>711 ヒープってオブジェクトをインスタンス化したときに割り当てられるメモリ領域って認識なんですが合ってますか? Cは関数内で宣言したローカル変数に配列を代入しても関数外に引き継げないのでまだわかるのですが、C++の考え方が掴めず混乱してます…… >>706 ヘタレか? お前の喧嘩を買ってやると言っているのだから、 馬鹿パヨク韓国人なりの論理を展開してみろよ。 状況としては、2chは地域の公園のようなもので、 誰でも自由に入って楽しむことは出来るが、 飼い犬のウンコをまき散らして帰るような奴は二度と来るな、と当然思われる。 それを俺は、はっきり言ってやってるだけだ。 お前らは馬鹿すぎて理解できないようだから、直接的に言うしかない。 韓国人死ね で、それで俺を嫌うのはお前らの自由だが、当然それでは何も解決しない。 お前らが迷惑行為を続け、他の連中に嫌われ続けるのも変わらないからだ。 何でも他人のせいにして被害者ぶるのはマジでムカつかれるから止めた方がいい。 嫌われる原因はお前ら自身にある。特に匿名掲示板ではそうだ。 ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる