2

私はこれを持っていてStructType st = StructTypeSecondInstance->st;、セグメンテーション違反を生成します。奇妙な部分は、スタックバックトレースが私に示すときです:

0x1067d2cc: memcpy + 0x10 (0, 10000, 1, 1097a69c, 11db0720, bfe821c0) + 310
0x103cfddc: some_function + 0x60 (0, bfe823d8, bfe82418, 10b09b10, 0, 0) +

では、構造体の割り当ては使用しmemcpyますか?

4

4 に答える 4

5

わからない。小さな構造体はレジスターに保持されることさえあります。使用されるかどうかmemcpyは、実装の詳細です(実装で定義されているか、指定されていないかは、コンパイラーの作成者が選択したものであり、文書化する必要はありません)。

C標準の観点から、重要なのは、割り当て後、宛先構造体の構造体メンバーがソース構造体の対応するメンバーと等しくなることです。

コンパイラの作成者は、おそらく構造体のサイズに基づいて、速度と単純さの間でトレードオフを行うことを期待します。大きいほど、を使用する可能性が高くなりますmemcpy。一部のmemcpy実装は非常に洗練されており、長さが2の累乗であるかどうか、またはsrcポインターとdstポインターの配置に応じて、異なるアルゴリズムを使用します。なぜ車輪の再発明をしたり、インラインバージョンのコードでコードを爆破したりするのmemcpyですか?

于 2012-09-13T10:02:07.527 に答える
2

そうかもしれません。

これは驚くべきことではありません。構造体の割り当てでは、大量のバイトをある場所から別の場所にできるだけ早くコピーする必要があります。これは、たまたま正確memcpy()に得意なことです。コンパイラーのライターであれば、呼び出しを生成するのは簡単なことのように思えます。

memcpy()これは、パディングをスキップできないため、多くのパディングを含む構造体を割り当てると、最適な方法よりも効率が低下する可能性があることに注意してください。

于 2012-09-13T09:56:14.480 に答える
1

この標準では、割り当て(またはその他の演算子)がコンパイラーによって実際にどのように実現されるかについては何も述べられていません。コンパイラが(たとえば)ソースファイル内のすべての操作に対して関数呼び出しを生成するのを止めるものは何もありません。

コンパイラには、最適と思われる割り当てを実装するためのライセンスがあります。ほとんどの場合、ほとんどのプラットフォームのほとんどのコンパイラでは、これは、構造が適度に小さい場合、コンパイラが移動命令のインラインシーケンスを生成することを意味します。構造が大きい場合は、memcpyを呼び出すのが一般的です。

ただし、コンパイラがランダムなビットフィールドの生成をループして、そのうちの1つが割り当てのソースと一致したときに停止することは完全に有効です(このアルゴリズムをbogocopyと呼びましょう)。

非ホスト操作をサポートするコンパイラーは、通常、使用可能な(または完全な)libcのないプラットフォームをターゲットにしている場合に、そのようなlibcallの発行をオフにするスイッチを提供します。

于 2012-09-13T10:23:09.967 に答える
0

コンパイラとプラットフォームによって異なります。大きなオブジェクトの割り当てにはを使用できますmemcpy。しかし、それがセグメンテーション違反の理由であってはなりません。

于 2012-09-13T09:56:48.793 に答える