理解したい:
char[1]
なぜCのaがchar*
(なぜこれを行うのか?)として使用されることがあるのはなぜですか?- 内部の仕組み(何が起こっているのか)
次のサンプルプログラムを提供します。
#include <stdio.h>
#include <string.h>
struct test_struct {
char *a;
char b[1];
} __attribute__((packed)); ;
int main() {
char *testp;
struct test_struct test_s;
testp = NULL;
memset(&test_s, 0, sizeof(struct test_struct));
printf("sizeof(test_struct) is: %lx\n", sizeof(struct test_struct));
printf("testp at: %p\n", &testp);
printf("testp is: %p\n", testp);
printf("test_s.a at: %p\n", &test_s.a);
printf("test_s.a is: %p\n", test_s.a);
printf("test_s.b at: %p\n", &test_s.b);
printf("test_s.b is: %p\n", test_s.b);
printf("sizeof(test_s.b): %lx \n", sizeof(test_s.b));
printf("real sizeof(test_s.b): %lx \n", ((void *)(&test_s.b) - (void *)(&test_s.a)) );
return 0;
}
次の出力(OS X、64ビット)が表示されます。
sizeof(test_struct) is: 9
testp at: 0x7fff62211a98
testp is: 0x0
test_s.a at: 0x7fff62211a88
test_s.a is: 0x0
test_s.b at: 0x7fff62211a90
test_s.b is: 0x7fff62211a90
sizeof(test_s.b): 1
real sizeof(test_s.b): 8
メモリアドレスを見ると、構造体でさえ9バイトの大きさであり、16バイトが割り当てられていることがわかります。これは。が原因のようchar b[1]
です。しかし、これらの余分なバイトが最適化/ memアライメントの理由で割り当てられたのか、それともCのchar配列の内部処理に関係しているのかはわかりません。
実際の例は次の場所で見ることができます<fts.h>
:
`man 3 fts`は、構造体メンバー`fts_name`を次のように表示します。
char *fts_name; /* file name */
/usr/include/fts.hは、メンバーを次のように定義します。
char fts_name[1]; /* file name */
結局、fts_name
実際にはC文字列へのポインタとして使用できます。たとえば、printf("%s", ent->fts_name)
作品を使ってstdoutに印刷します。
したがって、achar[1]
が実際に1バイトの大きさである場合、64ビットマシンではメモリポインタとして使用できません。一方、これを本格的なものとして扱うこともchar *
機能しません。上記の出力でわかるtest_s.b is
ように、NULLポインターが表示されるはずです...