つまり、struct\memory 内の変数へのポインターを指定してから、それを何らかの関数に指定すると、struct\memory の先頭へのポインターが表示されます。それを行う機能はありますか?
この質問を理解するには:
char* ptr=((char*)malloc(12))+3;
//MemStart(ptr) == ptr-3
MemStart
' は、コードでその結果を与える関数になります。
つまり、struct\memory 内の変数へのポインターを指定してから、それを何らかの関数に指定すると、struct\memory の先頭へのポインターが表示されます。それを行う機能はありますか?
この質問を理解するには:
char* ptr=((char*)malloc(12))+3;
//MemStart(ptr) == ptr-3
MemStart
' は、コードでその結果を与える関数になります。
メモリ内のその構造体の表現に固有のもの (常にバイト 0xff、0xff で始まるなど) がない限り、特定の構造体または配列の開始位置を特定する方法はありません。現代のアーキテクチャはフォン ノイマンマシンです。つまり、メモリには固有の意味がありません。
多くのアーキテクチャにはアライメントの問題または最適化があることに注意してください。つまり、構造体または配列は 16 ビット、32 ビット、または 64 ビットのワード境界で開始する必要がある場合がありますが、これらはアーキテクチャ固有のものです。
【追記:以下追記しました】
ライブラリは、割り当てられたメモリ ブロックの先頭または末尾にガード バイトを導入したり、バッファ オーバーフローや誤ったポインタを探すために既知の定数でメモリを埋めたりすることがあります。ただし、これらは通常リリース モードでは省略され、存在する場合でも有効なデータである可能性があります。
動的に割り当てられたメモリのメモリ割り当てテーブルを調べることができますが、配列/構造体はヒープではなくスタックに割り当てられる可能性があります。また、配列内に構造体がある場合はどうなりますか? どの値が返されますか? 動的に割り当てられたメモリだけに制限したい場合、割り当てられたメモリの開始のみが必要な場合は、Basile が優れた回答を提供します。
ほとんどのmalloc
実装では、必要なものが提供されません (動的に割り当てられたブロックへの内部ポインターが与えられた場合の開始アドレス)。そして、規格はそのようなものを必要としません。したがって、ベースへのポインターとオフセットの両方を使用することをお勧めします (おそらく、C++ 内にそれらをパックして、ポインターのような錯覚class fat_pointer
を与えるなど)。operator*
operator->
malloc
もちろん、上記のオペレーティング システム メモリ セグメント割り当て (つまり、Linux または Posix ではmmap(2)munmap(2)
) および割り当て解除プリミティブ syscallを独自に再実装することもできます。
専用のアロケーターを使用することもできます。posix_memalignを使用して大きな 2 の累乗アラインメント (たとえば 256 または 4096 バイト) でゾーンを割り当ててintptr_t
から、ポインターのキャストでビット操作を使用する場合があります。
深刻なメモリ アロケータを実装するということは、オペレーティング システムとアーキテクチャ (アライメントなど) の移植性のない詳細に注意を払うことを意味することに注意してください。
Boehmの保守的なガベージ コレクターを使用するGC_malloc
こともできます。次に、あなたが望むことを正確に行う関数があります:malloc
GC_free
GC_base
/* Return a pointer to the base (lowest address) of an object given */
/* a pointer to a location within the object. */
/* I.e. map an interior pointer to the corresponding bas pointer. */
/* Note that with debugging allocation, this returns a pointer to the */
/* actual base of the object, i.e. the debug information, not to */
/* the base of the user object. */
/* Return 0 if displaced_pointer doesn't point to within a valid */
/* object. */
/* Note that a deallocated object in the garbage collected heap */
/* may be considered valid, even if it has been deallocated with */
/* GC_free. */
GC_API void * GC_base(void * displaced_pointer);
offsetof()
次のマクロを使用できます<cstddef>
。
#include <cstddef>
#include <iostream>
using namespace std;
typedef struct
{
int a;
int b;
} S;
int main()
{
S s = { 1, 2 };
cout << "address of s:" << &s << endl;
cout << "address of s.a:" << &s.a << endl;
cout << "address of s.b:" << &s.b << endl;
int* pb = &s.b;
S* ps = (S*)((char*)pb - offsetof(S, b));
cout << "ps:" << ps << endl;
return 0;
}
出力 ( ideone ):
address of s:0xbffd266c
address of s.a:0xbffd266c
address of s.b:0xbffd2670
ps:0xbffd266c