web-dev-qa-db-ja.com

mallocされたメモリでsizeof()を使用する

重複の可能性:
mallocとsizeofに関する初心者の質問

文字列をプログラムに読み込もうとしています。文字列が破損していることに気付いたとき、次のコードを試しました。

 void *mallocated = malloc(100);
 printf("sizeof(mallocated) = %d\n", sizeof(mallocated));

私のプログラムによると、mallocatedのサイズは8でしたが、100バイトを割り当てました。このため、8バイトより長い文字列を格納しようとすると、8バイト以降のすべてが消えることがあります。なぜこれが起こっているのですか、そしてどうすればそれを防ぐことができますか?

15
Michael Dickens

「文字列」ポインタのサイズが8バイトだからです。 sizeof()を適切な「サイズ」で使用する例を次に示します。 size_of()という用語は、それを使用することに慣れていない人々を欺くことがあります。あなたの場合、ポインタのサイズは8バイトです。以下は典型的な32ビットシステムでの表現です。

_sizeof (char)   = 1
sizeof (double) = 8
sizeof (float)  = 4
sizeof (int)    = 4
sizeof (long)   = 4
sizeof (long long)  = 8
sizeof (short)  = 2
sizeof (void *) = 4

sizeof (clock_t)    = 4
sizeof (pid_t)  = 4
sizeof (size_t) = 4
sizeof (ssize_t)    = 4
sizeof (time_t) = 4
_

ソース

文字列が消えていると判断する方法を省略しています(char配列)。おそらく関数に渡されているので、明示的な長さを変数として渡すか、どこかで追跡する必要があります。 sizeof()を使用しても、これはわかりません。

私の 前の質問 を参照してください。これについては、私の最初の理解の欠如さえもわかります。

18
user195488

C89では、sizeof演算子は、コンパイル時にバイト単位の変数のサイズのみを検出します(この場合、8バイトのvoidポインター)。サイズはコンパイル時にわかっているため、プレーン配列で期待どおりに機能します。

char arr[100]; // sizeof arr == 100
char *p = arr; // sizeof p == 4 (or 8 on 64-bit architectures)
char *p = malloc(100); // sizeof p == 4 (or 8). Still!

ヒープに割り当てられたメモリのサイズを知るには、手動で追跡する必要があります。sizeofは役に立ちません。

10
Alex B

sizeofはポインタのサイズを返します(void *)割り当てたメモリのサイズではなく、指定したもの。後で使用する場合は、メモリのサイズを別の変数に格納する必要があります。

9
Kyle Lutz

それはいけません。指摘したように、void *のサイズが正しく割り当てられていない可能性がありますが、それではあまりわかりません。

あなたできませんマローされた*mallocatedのサイズを取得します。つまり、独自のメモリ管理ルーチンを作成しない限り、(この例では)100を返す関数呼び出しはありません。

最も簡単なのは、どこかでそれを覚えておくことです...多分..。

stuct {
  void *data;
  unsigned int size
 } myStructureWhichRemebersItsSize;

myStructureWhichRemebersItsSize *someData;
someData.data = malloc(100);  // and check for NULL
someData.size = 100;
4
Mawg

_void*_は、何が含まれているかわからない場合のメモリ内の場所のタイプです。避けるべきです。

_char*_は、charを保持するメモリ内のある場所を指す値のタイプです。メモリ内の場所の識別には8バイトかかります。

sizeofは、特定のタイプが必要とするバイト数を示します。 mallocで割り当てられた数ではなく、メモリコンパイラがタイプを認識している量should take。 sizeofを値に適用することは、しばしば悪いスタイルと見なされ、ここで他の誰かが言及したように、C99でスマートな動作を呼び出すことがあります。

_char[100]_ 100文字を保持する値のタイプ。 _char[100] a;_は、スタック上の100 charsの文字列です。

char(*)[100]は、100文字を保持する値へのポインタのタイプです。 char(*b)[100];は、bが100文字を指すようにします(おそらくヒープ上にあります)。あなたがおそらく欲しいのは

_char (*s)[100] = malloc( sizeof( char[100] ) );
printf( "%u byte pointer to %u bytes of size %u elements\n",
  sizeof s, sizeof *s, sizeof **s );
_
0
Potatoswatter