メモリブロックのサイズは通常、ポインタのすぐ下に格納されます。これはハックですが(あなたは私ができると言っていました...)、次のコードが私のLinuxボックスで実行されます:
#include <stdio.h>
#include <stdlib.h>
int main(){
int *p, n=123;
p = (int*)malloc(n*sizeof(int));
printf("allocated %d bytes for p\n", n*sizeof(int));
printf("p[-2] : %d \n", *(p-2));
printf("malloc_useable_size(p) : %d\n", malloc_usable_size(p));
free(p);
}
生成される出力は次のとおりです。
allocated 492 bytes to p
p[-2] : 513
malloc_useable_size(p): 504
p [-2]のサイズは正確ではないことに注意してください492
。ハウスキーピングや境界の調整などにより、追加のスペースが消費されます。
また、注意してください-これはgcc
コンパイラで機能しました。しかしg++
、ポインタ変換について不平を言い、私は宣言していませんでしたmalloc_useable_size()
。@fanlの答えを見た後、好奇心からその行を追加しました。mallinfo
@OliCharlesworthの回答を見た後の出力も少し遊んでみました。
nの値を変更すると、状況が非常によく一致することがわかります。たとえば、n(上記のコードで)を100から119にステップすると、対象となるさまざまな変数の値は次のようになります。
n | p[-2] | usable | uordblks
----+-------+--------+---------
100 417 408 416
101 417 408 416
102 417 408 416
103 433 424 432
104 433 424 432
105 433 424 432
106 433 424 432
107 449 440 448
108 449 440 448
109 449 440 448
110 449 440 448
111 465 456 464
112 465 456 464
113 465 456 464
114 465 456 464
115 481 472 480
116 481 472 480
117 481 472 480
118 481 472 480
119 497 488 496
usable
との間、およびp[-2]
との1
間には常に9の違いがp[-2]
ありuordblks
ます。このメソッドの利点は、要求した内容、つまりこのポインターのサイズがp[-2]
正確にわかることです。他の呼び出しは実際にあなたが本当に欲しかったものをあなたに伝えるかもしれません...
PS非常に大きなメモリブロックの場合、にあるを調べる必要がある可能性がありlong integer
ます*((long int*)(p)-1)
。それは私に素晴らしいマクロのインスピレーションを与えてくれます:
#define PSIZE(a) (*((long int*)(a)-1))
次に、ポインタのサイズを次のように確認できます。
printf("my pointer size is %ld\n", PSIZE(myPointer));
ポインタの種類を気にする必要はありません。これがさまざまなタイプのポインター、および4Gを超えるブロックで機能することを確認しました。明らかに、数値がmallinfo()と正確に一致するように、マクロで1を引くことを決定できます。
編集:ポインタのすぐ下に何が格納されているかについてのより完全な説明は、この以前の質問に対する回答の1つに記載されています。これは、私が観察した「+1」が実際にはLSBに格納されているフラグによるものであることを示しています。正しいアプローチは、結果を〜3でANDし、2つのLSBをクリアしてから、結果から(long int *)のサイズを減算することです(実際には、元の回答は2 * sizeof(unsigned long int)を減算しますが、それは間違い):
#define PSIZE(a) ((*((long int*)(a)-1))&~3 - sizeof(long int*))
リンクされた回答では、これをデバッグのみに使用し、実際のコードに依存しないことを強くお勧めします。私はその警告を繰り返さざるを得ないと感じています。