C++相談室 part148

レス数が900を超えています。1000を超えると表示できなくなるよ。
2020/01/31(金) 20:54:06.26ID:Nt0XFA2s
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。

前スレ
C++相談室 part147
https://mevius.5ch.net/test/read.cgi/tech/1576659413/
このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.105【環境依存OK】
http://mevius.5ch.net/test/read.cgi/tech/1556142878/

■長いソースを貼るときはここへ。■
 http://codepad.org/
 https://ideone.com/

[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
2020/02/13(木) 20:08:49.19ID:J94ypinO
delete [] pと同じように
sizeof [] pを用意すりゃいいのにね
pがnew []されてなかったら誤動作するって挙動ならdeleteと同じだろうに
2020/02/13(木) 20:15:32.26ID:iivZofrB
言いたいことは分かるが構文がきもい
2020/02/13(木) 20:17:34.65ID:Y6SS1xK+
欲しいなら作れば?
それができるのがc++じゃん
2020/02/13(木) 20:36:41.73ID:ImKshd8q
>>791
>C++の配列は長さの情報を持ってないってことになってるけど
>長さを与えなくてもdelete[]できるんだから、メモリのどこかにその情報はあるよね?

new したときは、その領域サイズが実行時にユーザーのみえないところに保存される、というだけなのでは?
C/C++ の配列は長さ情報を(自分でそう書かないかぎり)持たないとおもいますよ
816デフォルトの名無しさん
垢版 |
2020/02/13(木) 20:38:39.62ID:WjLTLikp
ちゃうねん。
2020/02/13(木) 20:50:05.52ID:qzSQSiwu
設計がダメな場合コンパイラにいくら指摘されようと根本的には治らんのだが、
(たいていそういう馬鹿はコンパイラ通すためにmut,RefCell,unsafeを使いまくる)
そういうのを少しもわかってないバカがrust推しなんだよなぁ。
構造体を1から作り直さなきゃならんかったり根本的に間違ってる。
2020/02/13(木) 21:00:18.27ID:sl9OX6cI
>>808
new TYPE[]するとき内部的にサイズ情報を持つ保証ってあったっけ?
例えば自前でoperator new []を実装するとき、予め2^nバイトのブロックを所定の数用意しておいて、要求サイズに応じて必要十分な大きさのブロックを返すなら、割り当て時に要求されたバイト数または要素数の情報を保持しないという実装も可能かと思う。
2020/02/13(木) 21:18:32.64ID:9NIgZq2/
>>811
いえいえ
2020/02/13(木) 21:37:18.24ID:Y6SS1xK+
>>818
デストラクタ呼ぶ必要ある
2020/02/13(木) 21:39:24.09ID:J94ypinO
デストラクタ呼ぶ必要ない型だと、size情報持ってないと言うことなんだろうね
2020/02/13(木) 21:40:36.17ID:sl9OX6cI
>>820
デストラクタの実装も、返ってきたアドレスの値でどのサイズの領域か(割り当て要求されたサイズではなく、自分で区切ったブロックのサイズ)が分かるようにしておけば大丈夫でないかな?
2020/02/13(木) 21:41:24.98ID:sl9OX6cI
>>822
すまん、勘違いでした。全部忘れてください
824デフォルトの名無しさん
垢版 |
2020/02/13(木) 22:02:22.87ID:WjLTLikp
はい忘れました。
2020/02/13(木) 22:06:16.93ID:Bk3UL691
アドレスだけじゃなくて長さも受け渡しするインターフェースにしましょうとしか。
826デフォルトの名無しさん
垢版 |
2020/02/13(木) 22:36:33.13ID:WjLTLikp
シリアル化の王道ってありますか?
2020/02/13(木) 22:45:19.55ID:iq5JxXln
オブジェクトならCORBA、データ構造だけでいいならASN.1とか。
2020/02/13(木) 22:54:55.06ID:tx2lxPGZ
>>822
TYPEがデストラクタを持つclassの場合に、ptr = new TYPE[n] で確保されたメモリ
を delete[] ptr とすると、 正確に n 回デストラクタを呼び出す必要がある。
new が n * sizeof(TYPE) より大きめのブロックを確保した場合でも、
delete[] ptr 時に正確な n の値を割り出す方法が必要となる。
なので、n の値は ptr の値さえあれば知ることが出来ることが必要条件となる。
つまり、少なくともデストラクタを持つ TYPE の場合に TYPE の配列をヒープから
確保した場合には、配列の要素数を必ず配列の先頭のポインタの値から「知る」事が出来る。
829デフォルトの名無しさん
垢版 |
2020/02/13(木) 23:01:33.00ID:WjLTLikp
>>827
もうちょっと簡単なのないですかね。
型情報要らないんで。
2020/02/13(木) 23:09:58.23ID:iq5JxXln
型情報が無けりゃデシリアライズしても使いようがあるまい。
831デフォルトの名無しさん
垢版 |
2020/02/13(木) 23:12:32.63ID:WjLTLikp
それがあるんですよ兄さん。
2020/02/13(木) 23:12:57.71ID:ktN45haN
双方向mapって何使うのがいいですか?boostのbimap?
それともこのくらいは自作してる人のほうが多いですか?
833デフォルトの名無しさん
垢版 |
2020/02/14(金) 00:05:24.00ID:CPLKNT1n
双方向Mapって何に使えるんですか?
2020/02/14(金) 01:54:24.23ID:0WgbwkuV
型情報ないならそもそもデシリアライズできないし
型情報なしで成り立つ、つまり型情報を事前に知っている前提なら
バイナリでそのまま送ればいいだろ
2020/02/14(金) 02:05:36.33ID:raWqkpxU
型がわかっててもコンテナはそのままではバイナリで送れない
836デフォルトの名無しさん
垢版 |
2020/02/14(金) 02:11:15.54ID:CPLKNT1n
>>834
そのやり方教えて。
あめさんあげるから。
2020/02/14(金) 07:52:45.40ID:RsXMnrpQ
ちゃんとやるならPODに詰め替えてからchar配列へreinterpret_cast
2020/02/14(金) 09:19:01.22ID:nLeEzkye
>>826
シリアル化ってのにどういう要件を置くかだな。
同じ環境でデシリアライズ出来ればよいのであれば >>837 で十分だろうし、
データ形式が決まってて (あるいはデータ形式の側を中心に策定したくて)
それのシリアライズとデシリアライズを (それぞれ別の環境で (ときには言語も違うかも)) やりたいということなら
protobuf などのツールを使うのはよい案だと思う。
2020/02/14(金) 13:35:07.90ID:vZZ7SPTm
boostにあるじゃないですか
googleのなんか使うんじゃありません
840デフォルトの名無しさん
垢版 |
2020/02/14(金) 13:41:23.49ID:a5iC3cHy
>>791
>>807
実装依存だと思うけど hoge[-1] あたりに格納されてた
2020/02/14(金) 13:49:57.91ID:rQdJoGM9
>>840
VC++の場合、ptr = new TYPE[n] で確保された場合は、確かに
ptr[0] == n
になっていた気がする。
「確かに」というのは言葉のあやで、厳密には覚えてないが、
VC++の new で使われる組み込み関数のライブラリのソースコードを見ると分かる。
2020/02/14(金) 13:50:28.63ID:rQdJoGM9
>>841
すまん、
ptr[-1] == n
の間違い。
843デフォルトの名無しさん
垢版 |
2020/02/14(金) 14:03:39.33ID:a5iC3cHy
>>807
>>841
OSやコンパイラで違うんでしょ
https://ideone.com/DuTmC5
2020/02/14(金) 15:26:11.39ID:rQdJoGM9
>>842
あ、すまん、正しくは、大体、
 ((DWORD *)ptr)[-1] == n
だ。
ptr[-1] だと、sizeof(TYPE)分、アドレスが戻ってしまうし、
結果の型も DWORD とかではなく、TYPE 型になってしまう。
2020/02/14(金) 15:28:19.59ID:rQdJoGM9
>>843
言っておくが、new char[n] とかでは、駄目な可能性は有るよ。
話は、「TYPEがデストラクタを持つとき」のnew TYPE[n]に限定。
2020/02/14(金) 17:17:51.62ID:jFoBh/u0
一時オブジェクトの寿命について、ご教示ください。
例えば、以下のようなコードがあった時、

void foo(const char* c); // 外部ライブラリの関数につき変更不可とする
void main()
{
const std::string s = "aaa";
foo((s + "bbb").c_str());
}

一時オブジェクトstring(s + "bbb")の破棄が行われるのは、
関数foo()を呼ぶ前でしょうか、呼んだ後でしょうか。
調べた範囲では、「完全式の終わり」という話が出てきたのですが、
どこまでが完全式なのか判断できませんでした。
2020/02/14(金) 17:22:07.67ID:nLeEzkye
>>846
この場合はその行の終わり。
セミコロンのところだと思っていい。
2020/02/14(金) 17:34:07.49ID:nLeEzkye
すごくどうでもいい話なんだけど、
JIS では完結式という用語を使ってるのに完全式って言葉の方がよく使われているよね……。
2020/02/14(金) 17:59:01.70ID:nLeEzkye
>>846-847
式の一部であるような式が部分式で、
そうでないような式が完結式って言う。
850デフォルトの名無しさん
垢版 |
2020/02/14(金) 19:29:16.13ID:CPLKNT1n
>>837-838
ありがとん。
851846
垢版 |
2020/02/14(金) 19:44:55.13ID:jFoBh/u0
>>847-849
ご回答ありがとうございます。
大変勉強になりました。
2020/02/14(金) 20:52:54.21ID:x/oqiD9H
おいCぺろぺろ
2020/02/14(金) 20:58:59.55ID:V/oEZCXU
>>851
いえいえ
854デフォルトの名無しさん
垢版 |
2020/02/15(土) 10:34:21.20ID:BMoFghq4
newって意外と速いんだな。
アクセスは不利かもしれないけど。
2020/02/15(土) 12:11:39.70ID:DzNKB5Jj
>>854
速いよ。
高速なゲームでも普通に使える。
856デフォルトの名無しさん
垢版 |
2020/02/15(土) 12:12:59.04ID:BMoFghq4
でもスタックは常にキャッシュに乗ってるから、そこらへんでどう変わるのかな。
2020/02/15(土) 13:19:54.61ID:J1bovO5o
キャッシュに乗るくらいの量だったらそもそもクリティカルな重さにはならんだろ。
newで問題になるのは10万とかそのくらいのオーダーをがっつりfor文で呼ぶとかそれくらいのことする場合。
858デフォルトの名無しさん
垢版 |
2020/02/15(土) 13:21:27.11ID:BMoFghq4
スタックは常にキャッシュに乗ってる。
2020/02/15(土) 13:23:13.35ID:lTU5fwx1
>>857
風邪が騙りかけます
2020/02/15(土) 14:11:39.55ID:DzNKB5Jj
>>857
VC++の場合、コンストラクタが無い場合、new が必要とする時間は 170クロック。
3.0GHz の CPUの場合、1.7 * 10^7 回(1,700万回)くらい new してやっと一秒
位。
だから、問題になるのは、1万回ループではなく、100〜1000万回くらいのループ。
2020/02/15(土) 14:15:19.79ID:DzNKB5Jj
もちろん、スタック変数で済むならスタック変数の方がいい。
ただ、スタックは容量に限りがあるので全部スタックという訳にもいかない。
ヒープにも限りはあるにはあるが、それは OSやマシンの限界。
862デフォルトの名無しさん
垢版 |
2020/02/15(土) 14:25:57.86ID:BMoFghq4
そこでgotoなんですよ。
863デフォルトの名無しさん
垢版 |
2020/02/15(土) 14:43:25.87ID:BMoFghq4
コレクションがソートの有無でだいぶ変わる。
trie_base_benchmark__sorted_words_1
trie assign.
409ms
size : 466551
words : 466551

trie insert.
762ms
size : 466551
words : 466551

std::set insert.
69ms

std::unordered_set insert.
149ms

(assigned) trie find.
24ms

(inserted) trie find.
25ms

std::set find.
194ms

std::unordered_set find.
63ms
864デフォルトの名無しさん
垢版 |
2020/02/15(土) 14:44:57.19ID:BMoFghq4
trie_base_benchmark__random_words_1

trie assign.
2034ms
size : 466551
words : 466551

trie insert.
2026ms
size : 466551
words : 466551

std::set insert.
490ms

std::unordered_set insert.
146ms

(assigned) trie find.
158ms

(inserted) trie find.
169ms

std::set find.
477ms

std::unordered_set find.
62ms
865デフォルトの名無しさん
垢版 |
2020/02/15(土) 14:46:37.02ID:BMoFghq4
挿入速度が変わるのは仕方ないとしても、検索速度が変わるのは、キャッシュじゃないかと思うんだけど。
866デフォルトの名無しさん
垢版 |
2020/02/15(土) 14:49:41.43ID:BMoFghq4
std::sort: 306ms, (466551count).
先にソートしてから挿入したほうが速度的にお得っぽい。
2020/02/15(土) 16:03:09.29ID:0hgUDlXi
>>854
速いといっても
単純な演算と比べれば劇遅
2020/02/15(土) 16:18:40.81ID:qSK05WKV
>>867
とにかく、足し算/引き算が1クロック程度、new が170クロック程度だからね。
使い方を間違えなければ劇遅とはいえまい。
2020/02/15(土) 16:32:01.46ID:4O8uAQVX
auto hentai = SM(std::move(羞恥心));
870デフォルトの名無しさん
垢版 |
2020/02/15(土) 17:12:18.08ID:BMoFghq4
newより+のほうが速いってことか。
871デフォルトの名無しさん
垢版 |
2020/02/15(土) 17:25:57.34ID:BMoFghq4
+と-ならどっちが速いんだろう。
2020/02/15(土) 17:49:06.00ID:cwLPNCdO
>>871
回路はほぼ共有してるんじゃないの?
2の補数を使うのもそれが理由なんだろうし。
少なくとも Pentium 時代まではクロックは同じだったはず。

近頃の事情は知らんけど
GCC あたりで強い最適化をかけてみても引き算か足し算を特に避ける様子もないので、
まあだいたい同じなんでしょ。
2020/02/15(土) 18:01:50.38ID:zARYy4pH
>>870
C++の場合、+ひとつだけでも裏でどんなコードが動くか油断ならない。
2020/02/15(土) 18:13:26.25ID:2RWOAy2H
>>871
+ と - で速度が違うCPUは見たことがない

- は順番が関係あるので
処理によっては遅い事がある

b = 1 + b
b = 1 - b
2020/02/15(土) 18:14:19.52ID:cwLPNCdO
整数だけの話じゃなくてってことか。
ある程度の常識的判断が出来る場合もあるけど、
基本的には実装次第だわな。
2020/02/15(土) 18:19:46.61ID:2RWOAy2H
組み込み型じゃなけりゃそりゃね
+ でミサイル発射とか
2020/02/15(土) 19:02:33.35ID:qSK05WKV
>>870
new より + の方が 170 倍速いと言うことだ。
2020/02/15(土) 19:04:43.75ID:cVttwiPD
>>874
一度bをnegateしてから足す処理系があるかもな
2020/02/15(土) 19:30:46.15ID:qSK05WKV
>>874
確かに引き算には順序があるので、足し算より最適化に不利になることがある。
2020/02/15(土) 19:48:11.00ID:x3vECiAE
if(bReaZyuu){
2020/02/16(日) 00:34:55.37ID:pXV6w9YM
if (false != bReaZyuu) {
2020/02/16(日) 00:35:58.12ID:pXV6w9YM
newが常に数百クロックで済むと思ったら
間違いかもしれん…
2020/02/16(日) 01:50:35.50ID:1DEBeg9G
経験的にはnewが遅いと思ったことは無い。
なお、コンストラクタの処理時間以外はnewはmallocと同じ速度。
ゲームメーカーでも必要な場合に malloc を使うことは問題ないとされている。
2020/02/16(日) 02:03:13.40ID:MPWqg8uW
new からしてmallocを呼んでる実装が多い気がする。
2020/02/16(日) 02:34:52.46ID:yR2k1LO6
そりゃnew用とmalloc用でヒープ別けたら無駄だし
2020/02/16(日) 02:36:27.06ID:VK9AAsv4
ヒープからの割り付けをする機会を減らすことで実行速度を上げる工夫はよく聞く話ではあるよな。
ただ、そこまでギリギリのチューニングが必要ってことがあまりないだけで。
2020/02/16(日) 07:37:50.08ID:Rlzwkt+8
newは最悪値が読めないからなぁ
組込とかシビアなゲームでは使い辛い
888デフォルトの名無しさん
垢版 |
2020/02/16(日) 08:25:44.50ID:Yy7z+EdH
具体的な数字が出てるとイメージが湧く。
889デフォルトの名無しさん
垢版 |
2020/02/16(日) 08:45:53.63ID:Yy7z+EdH
170クロックならあんまり気にする必要ないな。
2020/02/16(日) 10:26:07.87ID:w0IbR+6u
組み込みでc++がそもそもおかしい
2020/02/16(日) 11:00:34.43ID:1DEBeg9G
>>887
よっぽどでない限り、AAAゲームでも使われてるよ。
2020/02/16(日) 11:01:02.59ID:B02+i8yM
最近では小規模組み込みでもC++を使う事はあります

new / deleteやヒープを無効にしたり
newのみでdelete出来ないようにしたり
なんてこともあります
2020/02/16(日) 11:03:58.49ID:+vprjU7s
>>890
視野狭すぎ
2020/02/16(日) 11:12:03.97ID:w0IbR+6u
また馬鹿が無駄に一般化してできるワイ言ってんのか。。相変わらずだな。
2020/02/16(日) 11:20:41.43ID:+vprjU7s
日本語でおk
896デフォルトの名無しさん
垢版 |
2020/02/16(日) 11:23:16.68ID:Yy7z+EdH
ストリームってなんで遅いんだろね。
2020/02/16(日) 11:39:47.59ID:Rlzwkt+8
>>891
そりゃそういう例もあるわな
だから何?w
898デフォルトの名無しさん
垢版 |
2020/02/16(日) 11:42:38.67ID:Yy7z+EdH
スレで、do{}while()はダメっぽいこと書いてあったけど、なんでダメなの?
2020/02/16(日) 12:30:30.11ID:q7JzY0gs
>>887
でもお前は組み込みにもゲーム開発にも携わってないじゃん
2020/02/16(日) 12:42:15.06ID:Rlzwkt+8
>>899
ごめんねー、俺はプリンタ屋さんなのw
ゲームは知り合いの話ね
901デフォルトの名無しさん
垢版 |
2020/02/16(日) 12:54:36.44ID:Yy7z+EdH
プリンタ屋さんってどんな仕事ですか?
2020/02/16(日) 12:58:53.64ID:Rlzwkt+8
>>901
俺は制御周り、上位インターフェースからのデータを描画ルーチンにに渡したり、下位インターフェースにデータ渡したり、パネルとかの制御をやってる
描画部分はまた別の人がやってる
903デフォルトの名無しさん
垢版 |
2020/02/16(日) 12:59:56.11ID:Yy7z+EdH
なんか難しそうですね。
904デフォルトの名無しさん
垢版 |
2020/02/16(日) 13:01:18.53ID:Yy7z+EdH
プリンタってプロセッサはどんな感じのを使うんですか?
newってあるんですか?
905デフォルトの名無しさん
垢版 |
2020/02/16(日) 13:02:40.97ID:Yy7z+EdH
プリンタのヘッドについてる穴の数は決まっているんだから、あまりヒープが必要無さそうな気もする。
906デフォルトの名無しさん
垢版 |
2020/02/16(日) 13:03:59.79ID:Yy7z+EdH
std::vectorの上にヒープを作っても速度的に大丈夫なことは確認した。
2020/02/16(日) 13:07:31.29ID:Rlzwkt+8
昔はSHシリーズとかR2000とか
今はARMもそれなりに使ってる
制御だとnewは基本使わない
あと俺がやってるのは業務用のLBP
908デフォルトの名無しさん
垢版 |
2020/02/16(日) 13:08:47.09ID:Yy7z+EdH
ってことはキャノンですか。
909デフォルトの名無しさん
垢版 |
2020/02/16(日) 13:10:53.15ID:Yy7z+EdH
メモ問題は結局ホワイトボード買ってきた。
ホワイトボードをワンノートに撮影するという昔っぽいことに。
2020/02/16(日) 13:11:07.93ID:Rlzwkt+8
流石に社名までは出せんわw
911デフォルトの名無しさん
垢版 |
2020/02/16(日) 13:12:13.52ID:Yy7z+EdH
ワンノートのアンドロイド版はカメラにホワイトボードのモードがあるんだけど、テカリ消してくれないし、ホワイトバランスも調整してくれない。
レス数が900を超えています。1000を超えると表示できなくなるよ。