uint16_t x; typedef struct _fHead {    char                    name[256];    unsigned long   size;    bool                    isEnd;    char                    reserve[3];                // 予約領域} fHead; /Zp1 をコンパイルオプションに追加して1バイト境界にするとちゃんと261バイトになりました。. Win2K、VisualC++ 2005 Expressの環境で構造体のサイズが合わない現象が起きて困っています。, 構造体の内容としては256+4(unsigned long)+1(bool)で261バイトのサイズを返すことを期待したのですが、コードを実行すると264バイトと+3バイト多く返ってきます。, int size = 256 + sizeof(unsigned long) + sizeof(bool), この構造体のサイズを正しく取得する方法をご存知の方が降りましたら、ご教授願います。, コンパイルオプションが不明なので、不確定な部分もありますが、おそらくは構造体メンバのアライメントの関係だと思います。, #構造体メンバのアライメントって何?ということであれば、それはそれで質問してください。, ■その2#pragma pack(push, 1)typedef struct _fHead {    char                    name[256];    unsigned long   size;    bool                    isEnd;} fHead;#pragma pack(pop), ただ構造体のメンバアライメントを8より小さい値にすると、CPUとメモリーの構造上遅くなる場合があります。そのためメモリー上でのやりとりだけの場合は、速度のことを考えるとメンバアライメントを変更しないほうが良いでしょう。, どうしてもパックせざる得ないような状況があればしますが、そういう状況と言うのは殆ど無かったので。, ファイルフォーマットのデザインにしても4バイト境界を意識したデザインをしてますので. 電子計算機 > 仕様・構造 > ソフトウェア > プログラミング言語 > 言語仕様 > 予約語・関数など, C/C++で、構造体内にあるメンバーのオフセットを返す機能。多くの場合マクロとして実装される。, offsetof() は、構造体 type 中にあるフィールド member の、構造体先頭からのオフセットを size_t 型で返す。, オフセットはポインター差分に相当すると思われるが、ptrdiff_t 型などではなく、なぜか size_t 型で返す仕様となっている。, そうでなくても、コンパイラーによっては、環境にあわせてフィールド間にパディングを挿入したりフィールドの順序を入れ替えたりすることもあるため、メモリー空間への配置については実装により変動する。, このような現状から、フィールドのオフセットを定数として決め打ちすることは危険である。オフセットが必要な状況においては、このoffsetof機能は有用である。, なお、member がビットフィールドの場合は使用できず、コンパイル時点でエラーとなる。, /usr/lib/gcc/x86_64-linux-gnu/4.4/include/stddef.h, GCC 3.5から追加された独自の組み込み関数 __builtin_offsetof() を用いている。, 定義は、/usr/src/linux-headers-2.6.XX-XX/include/linux/stddef.h などにある。, AndroidのLinuxカーネルでも external/kernel-headers/original/linux/stddef.h に存在し、offsetof の定義は全く同じ内容である。, __compiler_offsetof()は、__builtin_offsetof()の別名である。, Visual C++ 12.0では、stddef.h で次のように定義されている。, さすがMicrosoftだけあって、(ptrdiff_t) でないとおかしいということに気づいた記述になっている。またC++でビルドすると、const volatile char&でreinterpret_castするようになっている。, オフセットとは基準からの差のことであり、求めたいメンバーのアドレスから、その構造体の先頭アドレスを引き算すればよいだけである。しかし、「その構造体の先頭アドレス」が0であれば、引き算が簡単である。そこで、このような難解な式に至った。, カッコの中のこの部分で、整数0を、入力された構造体名でキャストしてポインターとしている。これによって、このカッコ内には、アドレス0に配置された構造体のポインターが誕生する。, この部分は、構造体が配置されるアドレスに関わらず、先の構造体中のメンバーが指し示される。, さてこの構造体だが、最初の定義によりアドレス0に配置されている。構造体のアドレスが今回は0と特別に分かっている。-> によって配置アドレスが判明するが、構造体の先頭アドレスが 0 なので、この内容は実質的にオフセットと等価となる。. tpmparams 構造体を大雑把な目で見れば、サイズ4バイト( uint 型)のデータとサイズ16バイト( rect 型)のデータから構成されていると見ることができますし、細かく見ればサイズ4バイト( uint 型および long 型)のデータ5個から構成されていると見ることもできます。 #ポインタを構造体のサイズで進ませるようなものを作るときは気をつけないといけませんね... sizeofしている場合には適切に処理されますし、ポインタも+1では問題ないでしょう?, コンパイルオプションで指定するほかに、以下のようなコードで指定することもできますよ。■その1typedef __declspec(align(1)) struct _fHead {    char                    name[256];    unsigned long   size;    bool                    isEnd;} fHead;■その2#pragma pack(push, 1)typedef struct _fHead {    char                    name[256];    unsigned long   size;    bool                    isEnd;} fHead;#pragma pack(pop)■align - MSDNhttp://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/vclang/html/vcrefAlign.asp■pack - MSDNhttp://msdn2.microsoft.com/en-us/library/2e70t5y1(vs.71).aspx. こんにちは!フリーランスの長野です。 ポインタって使ってますか? ポインタの使い方を理解するのは最初はなかなか難しいかもしれません。c言語を学習する上では、どうしても手が止まってしまう部分で … 以下に offsetof マクロを使用したサンプルプログラムを示します. オフセットはポインター差分に相当すると思われるが、ptrdiff_t 型などではなく、なぜか size_t 型で返す仕様となっている。 uint16_t y; 構造体メンバのオフセット位置は、クラス名.メンバ名.offsetというクラスメソッドで取得できます。 class Point ( Structure ): _fields_ = ( ( 'x' , c_uint16 ), ( 'y' , c_uint16 ), ) Point . offset # 2 By following users and tags, you can catch up information on technical fields that you are interested in as a whole, By "stocking" the articles you like, you can search right away. といった感じで構造体のサイズを取得たいのですが、 構造体の内容としては256+4(unsigned long)+1(bool)で261バイトのサイズを返すことを期待したのですが、コードを実行すると264バイトと+3バイト多く返ってきます。 ちなみに、代わりに 構造体のポインタを指定したい場合はctypes.POINTER、ctypes.castでキャストしてあげます、ポインタが参照している値はcontentsで取得できます。, ctypes.stering_atでNULL終端の文字列を読み込み、Unicodeの場合はctypes.wstring_atを使います。 こんばんは。きわさです。 c言語の構造体のサイズ取得にハマったので、備忘録として残しておきます。 今回はc言語編です。 C言語で、構造体の変数の値を取得したいのですが、その際、他の変数に格納してある文字列を元に動的に行いたいのですが、可能でしょうか?イメージとしては、struct Entry{ char … 構造体のメンバはぎっちり詰まっていないことがある。 #pragma pack でアラインメントを変更できる。 メンバ変数の構造体の先頭からの位置は offsetof マクロで取得できる。 今回はちょっと長かったですね。次回もどうなることやら(汗)。 typedef struct _fHead {    char            name[256];    unsigned long   size;    bool            isEnd;    char            reserve[3];                // 予約領域} fHead; わたしもファイルやり取り・通信の場合は、PATIOさんと同じように、明示的に予約領域を記述しています。がこれはアライメント合わせのため空き領域が発生することを、はっきりと他の人に明示するためです。, その時使用したVC6ではデフォルトは8ですので、#pragmaで構造体のアライメントを明示的に4に指定していました。, えっと、Reservedのエリアですが、パディングを構造体エリア内にコードで設けるのは、言語仕様として規定されていなかったとおもうんですが?. What is going on with this article? """ #define container_of(ptr, type, member) ({          \, "Struct head address            = %p\n\n", "Struct head address from price = %p\n\n", "Struct head address from genre = %p\n\n", Linux Kernel: List構造を操作するためのAPI(Listの使い方), Linux環境でデスクトップアイコン(ショートカット)をfreedesktop.org仕様で作成する方法, Linux Kernel: prink(print kernel)によるメッセージ出力, AndroidにLinux環境を構築する”UserLAnd”がソースリーディング環境(スマホ用)として最適, DMM(現FANZA) API・Twitter Botによる自動広告を半年続けた結果、「得た収益」と「二度とやらないと誓った理由」, autofsを用いてHDD/SSD/USBメモリを起動時に自動マウントする方法(Debian), /etc/passwdに記載された/usr/sbin/nologin, /bin/falseとは何か【ログイン禁止】, 【Singeltonパターン】考え方は単純だが、使いどころが大切なデザインパターン【コード例はRubyとJava】, (type *)0)->memberは、変数memberを取得するため、便宜的にNULLポインタをキャストしています, 型を指定してポインタを得る理由は、コンパイル時に異常なアドレスを参照する事を防止したいから. 'struct'モジュールで沢山のデータを読もうとすると、フォーマットが呪文のようになりますので、大量のバイナリデータの読み込みをしっかりと書きたい場合はctypes.Structureクラスを使った方が良いでしょう。, C言語でintやshortはサイズが環境によって変化します、C99からint16_tやint32_tなどのサイズ固定の型指定が可能になったので、可能な限りサイズ固定の型指定を使用すべきです。それに伴いPython側でもctypes.c_intではなくctypes.c_int16などのサイズ固定の型を使いましょう。, ioまたはFILEのwriteにctypes.Structureインスタンスをそのまま渡せば書き込みができます。, readintoにctypes.Structureインスタンスをそのまま渡せば読み込みができます。, 構造体メンバのオフセット位置は、クラス名.メンバ名.offsetというクラスメソッドで取得できます。, C言語のmemsetとmemmoveと同等のものがctypes.memsetとctypes.memmoveです。, C/C++のように構造体のポインタをキャストすることにより、データをマッピングできます。 ctypes.Structreクラスと紛らわしいですね。, ctypes.StructureクラスでC/C++の構造体を扱う事ができます。 $ ./offsetof.exe member構造体の大きさ : 36 number (int) : 0 name (char [15]) : 4 age (short) : 20 sex (char) : 22 height (double) : 24 weight (float) : 32 $ スポンサーリンク コメントを残す コメントをキャン … container_ofマクロとは container_ofマクロは、Linux Kernelで用いられ、「構造体メンバポインタ」から「そのメンバを含む構造体の先頭ポインタ」を得られるマクロです。C言語では、offsetofマクロによって構造体メンバアドレスのオフセット(構造体先頭アドレスからメンバ変数までのオフセット なので、サイズを一定にする(したい)のであれば、コンパイルオプションなり、#pragma なりを使ってアライメント指定を強制しないと駄目だったような... コンパイラ同梱のSDKでは、コンパイラに合わせてこのヘッダーを書き換えることで、ソースのポータビリティを確保しています。, それこそ、VC の将来のバージョンでアライメント指定の方法が変わっても問題ないようになっています。, なので、コードで埋めるよりは、上記のように前後に、アライメント指定をいれるほうがよいとおもいますよ。, 私が行っている記述は言語仕様とか言語の規格に則ってというようなレベルのものではないです。, 今のマシンであれば、パックによる処理速度の低下と言うのも殆ど問題ならないと思うのですが、, また、一部の環境ではアライメントを意識したアクセスをしないとプログラムが不正終了するような, なので同じソースを色々な環境に持っていってと言うよりもアライメントを意識せよと言う話が, 先ですので処理効率の良いアライメントが違う環境では当然定義もコードも変わってきます。, あと、Reserverdに関しては単なるアライメント合わせだけの意味ではなくて追加が必要なときに, まあ、こういう考え方もあるよと言う話なので採用に関しては各自の判断と言う事でお願いします。, こちらについては同意。わたしもやります(最近は構造体にサイズフィールド持たせてバージョンチェック代りに利用することが増えましたけどw)。, アライメントの意識を常に持つという点も同意。これも重要ですね。この先 x64 や IA64 に移植するなんてことになった時に意識があるかないかでは、大きく変わる可能性がありますし。, ただ、パディングのために変数を定義だけは同意できないですね。こちらは、言語仕様的に問題がないとしても、なんでそこにそんなもの詰めてんの?というのがかならず発生します。, それと、スレとは直接的には関係ないですが、構造体をそのままファイルに落とし込むのも反対。, 16->32 のときのように、CPUアーキテクチャが変わるとか、それこそ、エンディアンの異なるCPUに移植するなどとなった場合、とてつもなく膨大な工数になって跳ね返ってきます。, 予定としてそんなものねーよとしていても、それが10年、20年後にもないとはいいきれませんから。, #なぜ、2000年問題があれだけ世間を賑わせたのか、そこにも理由の一端はありますw, 申し訳ありません。リクエストされたコンテンツは削除されています。すぐに自動的にリダイレクトされます。, http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/vclang/html/vcrefAlign.asp, http://msdn2.microsoft.com/en-us/library/2e70t5y1(vs.71).aspx. 構造体変数の定義が終わらないと、メモリアドレスが決定されないので、構造体変数を宣言する時点で、いきなり自分自身のメモリアドレスを使うことはできません。そのため、初期値としてとりあえず、null を与えています。 居が高いですが,入門書を読み終えた後に読むと非常に有益です., © Copyright 2010, C言語関数辞典 - Created by Kojo Sugita. c言語ではメモリのアクセスの効率化について考える必要がある。そんな今回は構造体におけるアライメントのお話を分かりやすく浅くしていきます。構造体サイズが予想より大きかった...。それパディングかもしれませんね。構造体を作るならアライメントを意識しましょう。 といった感じで構造体のサイズを取得たいのですが、 構造体の内容としては256+4(unsigned long)+1(bool)で261バイトのサイズを返すことを期待したのですが、コードを実行すると264バイトと+3バイト多く返ってきます。 ちなみに、代わりに