5

私はこのようなクラスを持っています:

class Object {
public: 
    unsigned char data[8];
    // other variables
    // functions etc...
 };

問題は、オブジェクト メンバーはすべて、オブジェクトに関連するメモリ内の同じ場所に格納されているかということです。char* data_ptr = array[0].dataしたがって、配列がある場合: char ポインターが 指定されたオブジェクト array[3] はdata_ptr + (sizeof(Object))、常に array[1].data を指しますか?

(クラスと構造体のデータ メンバー間にパディングが存在する可能性についての Q/A をいくつか読んだことがありますが、それらが私の質問に答えているとは思いません。)

前もって感謝します、ベン

4

5 に答える 5

4

sizeof Objectclass のすべての内部パディングがすでに含まれていますObject。最後にパディングを含めます。配列は追加のパディングを許可しません。data_ptr + sizeof Objectしたがって、が のアドレスを持つことは真ですarray[1].data

ただし、これが実際に許可されているかどうかはわかりません。つまり、コンパイラは、 8 (メンバー配列のサイズ)より大きい値を に追加することは決してないと想定できる可能があるため、ルールに違反すると失敗する最適化を適用する可能性があります。つまり、コードは実際には未定義の動作を示す可能性があります (これは、「この場合、コンパイラは何でも実行できる」という標準的な用語です)。dataarray[0].data

ただし、より寛容なルールがある へのポインターを使用しているcharため (一般的な型では実行できない多くのことをchar*実行できます)、実際には動作が定義されている可能性があります。

于 2012-08-19T10:00:04.340 に答える
2

あなたの質問の目的が、物事がどのように記憶されているかを理解することである場合、それは受け入れられます.

しかし、もしあなたが本当にそれをしたいなら: あなたがしたいことは、あなたの同僚全員に対して実際に犯罪です.

C++ でコレクションを処理する適切な方法は、配列を使用するのではなく、std::vector、または本当に必要な場合は別の std コレクションを使用することです。C の算術演算を使用する必要はなくなりましたが、イテレータを介してベクトル コレクションの項目にアクセスする必要があります。それがC++標準ライブラリの理由です:-)

于 2012-08-19T10:19:37.590 に答える
1

答えは「たぶん」だと思います。つまり、これに賭けるべきではないということです。最善の方法は、IDE デバッガーをいじってメモリ アドレスを検索することです。コンパイラが最適化できるメンバーとメソッドを導入すると、これは簡単に破棄される可能性があることがわかります。たとえば、静的である可能性のあるメンバーにアクセスしない定数またはメソッド。元:

void Object::doSomething() {std::cout << "something\n" << std::endl;}

((Object)NULL).doSomething();のメンバー変数を導入するまで、SEGFAULTなしで実際に機能することを最近知ったので、これは実際に静的割り当てに最適化されると思いますObject

于 2012-08-19T10:00:22.933 に答える
1

C++ のクラスのオブジェクトのサイズを決定する要因は多数あります。これらの要因は次のとおりです。 - すべての非静的データ メンバーのサイズ - データ メンバーの順序 - バイト アラインメントまたはバイト パディング - その直接の基底クラスのサイズ - 仮想関数の存在 (仮想関数を使用した動的ポリモーフィズム)。・使用コンパイラ ・継承方法(仮想継承)

ここをチェックしてください:http://www.cprogramming.com/tutorial/size_of_class_object.html

于 2012-08-19T10:00:43.737 に答える
1

はい、オブジェクトのベース アドレスに対するレイアウトは一定です。これは ABI の要件です。オブジェクトと配列の間隔またはパディングも、ABI によって指定されます。

于 2012-08-19T10:01:31.207 に答える