1. ホーム
  2. c++

[解決済み] Malloc vs new -- 異なるパディング

2022-10-01 10:02:17

質問

私は、高性能計算 (10^5 - 10^6 コア) 用に MPI を使用する私たちのプロジェクトのために、他の人の C++ コードをレビューしています。このコードは、異なるアーキテクチャ上の (潜在的に) 異なるマシン間の通信を可能にすることを目的としています。彼は、以下のような内容のコメントを書いています。

私たちは通常 newdelete を使っていますが、ここでは mallocfree . これは,コンパイラによっては new が使われると、異なるプラットフォーム間でデータを転送する際にエラーが発生するためです。このようなことは malloc .

これは、私が標準から知っていることとは一致しません。 newmalloc の質問をします。

new/deleteとmalloc/freeの違いは何ですか? は、コンパイラがオブジェクトのサイズを異なる方法で計算することができるという考えをほのめかしています (しかし、それではなぜ sizeof ?).

malloc & placement new vs. new はかなり人気のある質問ですが、ただ new がコンストラクタを使用している場合 malloc は使用しませんが、これはこの件とは関係ありません。

mallocはどのようにアライメントを理解するのでしょうか? は、メモリが適切にアラインメントされていることが保証されているのは new または malloc というのは、私が以前考えていたことです。

私の推測では、彼は過去のある時期に自分のバグを誤診して、次のように推論したのだと思います。 newmalloc は異なるパディングの量を与える、私はそれがおそらく真実ではないと思います。しかし、私はGoogleで答えを見つけることができませんし、以前の質問にもありません。

助けてください、StackOverflow、あなたは私の唯一の希望です!

どのように解決するのですか?

IIRCは1つだけ厄介な点があります。 malloc はどんな標準的な型に対しても整列されたアドレスを返すことが保証されています。 ::operator new(n) は任意の標準的な型に対してアラインされたアドレスを返すことだけが保証されています。 nより大きくない であり、もし T が文字型でない場合は new T[n] に対して整列されたアドレスを返すことが要求されるだけです。 T .

しかし、これはポインタの下位数ビットをフラグの格納に使用するような実装特有のトリックを行う場合、またはアドレスが厳密に必要以上にアライメントされていることに依存する場合にのみ関連しています。

オブジェクト内のパディングには影響しません。オブジェクトは、それが占めるメモリをどのように割り当てたかに関係なく、必然的にまったく同じレイアウトになります。したがって、この違いがデータ転送のエラーにつながるとは考えにくいのです。

そのコメントの著者がスタック上またはグローバル内のオブジェクトについて何を考えているか、彼の意見ではそれらが malloc のようにパディングされているのか、または new のようにパディングされているのか、何かしるしはありますか?それは、そのアイデアがどこから来たのかの手がかりを与えるかもしれません。

多分彼は混乱しているのでしょうが、多分彼の言っているコードは malloc(sizeof(Foo) * n)new Foo[n] . という感じかもしれませんね。

malloc((sizeof(int) + sizeof(char)) * n);

vs.

struct Foo { int a; char b; }
new Foo[n];

つまり、もしかしたら彼は と言い "私は malloc" を使っていますが というのは "構造体を使う代わりに、手動でデータをアラインメントされていない場所にパックしています" を意味します。実際には malloc は構造体を手動でパックするためには必要ありませんが、そのことに気づかないのは混乱の度合いが小さいからです。必要なのは、ワイヤを介して送信されるデータのレイアウトを定義することです。実装によっては 構造体 が使用される場合、実装によってデータの詰め方が異なります。