いくつかのメモリ割り当てで、これを見つけました。しかし、私はそれを理解していません。
char * mem_alloc()
{
char *point;
char *a;
point = (char *)malloc(block_num);
a = *(char**) point;
return a;
}
いくつかのメモリ割り当てで、これを見つけました。しかし、私はそれを理解していません。
char * mem_alloc()
{
char *point;
char *a;
point = (char *)malloc(block_num);
a = *(char**) point;
return a;
}
char * mem_alloc()
私の経験では、ポインターを返す関数は、ほとんどの場合、プログラム設計に欠陥があることを示しています。このようなポインターは、次の場所を指している可能性があります。
この場合、動的メモリを指しているため、プログラムの設計が不十分であり、メモリ リークが発生する可能性が高いと想定できます。
point = (char *)malloc(block_num);
このコードを書いた人は、malloc がどのように機能し、void ポインターがどのように機能するかについて混乱していることを意味します。malloc の結果は決して型キャストされるべきではありません。 thisおよびthisを参照してください。型キャストへの衝動は、プログラマーが C 言語について混乱していること、および/または C++ コンパイラーで C コードをコンパイルしようとしていることを意味します。
「block_num」は疑わしいです。これがグローバルで定数でない変数である場合、プログラムの設計が不十分です。
a = *(char**) point;
これは、ヒープ上の初期化されていないメモリを指しているポイントのアドレスを取得し、そのポイントがポインターツーポインターであると見なして、ヒープのガベージ コンテンツをポインターであるかのように扱うことを意味します。次に、ララランドのランダムな場所を指すこのポインターを呼び出し元に返します。そうしている間に、メモリリークが発生します。
Lundin's answer のコメントに投稿されたコード chenyoufu123 を見ると、次のようになります。
ptr = (char *)malloc(block_num * size);
for(k=0; k<block_num-1; k++) {
*((char **)(ptr + k*size)) = ptr + (k+1) * size;
}
*((char **)(ptr + k*size)) = NULL;
それはまだ悪いコードですが、質問の元のコードのように完全に無意味というわけではありません。特に、別のコメントからリンクされたリストを作成するために使用されるという発言とともに。
状況は、コードが「正しい」と仮定すると、
struct Node
{
struct Node *next;
/* More members */
};
およびsize_t size = sizeof(struct Node);
(名前はおそらく異なります)。それで
ptr = (char *)malloc(block_num * size);
block_num
連続するstruct Node
sにメモリを割り当てます。通常、それを次のように割り当てます。
struct Node *ptr = malloc(block_num * sizeof *ptr);
ループ
for(k=0; k<block_num-1; k++) {
*((char **)(ptr + k*size)) = ptr + (k+1) * size;
}
*((char **)(ptr + k*size)) = NULL;
k * sizeof(struct Node)
次に、メモリ ブロックの先頭の後ろのアドレスptr + k*size
をポインタへのポインタとして再解釈します (achar**
ですが、最近のほとんどの PC アーキテクチャでは、すべてのオブジェクト ポインタが同じ表現を持っているため、これは重要ではありません。重要な場合は、コードが壊れています)。とにかく)、次sizeof(struct Node)
のサイズのメモリチャンクのアドレスをその場所に書き込みます。next
ポインタは の最初のメンバであるため、リスト内の次のアドレスを現在の のポインタにstruct Node
書き込みます。最後に、最後のポインタを に設定します。struct Node
next
struct Node
next
struct Node
NULL
普段の書き方ですが、
struct Node *ptr = malloc(block_num * sizeof *ptr);
int k;
for(k = 0; k < block_um - 1; ++k)
{
ptr[k].next = &ptr[k+1]; // or ptr + (k+1), if you prefer
}
ptr[block_num-1].next = NULL;
char*
はより明確であるだけでなく、とstruct Node*
が異なるサイズまたは表現を持つプラットフォームで動作するという利点もあります。
a
が指す位置に格納されている値が含まれpoint
ます。は初期化されていないためpoint
、ランダムな値を含むランダムな場所をa
指しているため、最初からランダムな値を指しています。
したがって、コードはノーオペレーションです。
これは、ポイントの値 (アドレス) を設定するようです。
a = *(char**) point;
上記のステートメントは、「(char**) ポイント」部分の「ポインタへのポインタ」へのポイントを型キャストしています。この後、参照解除用の * が
あり、(ポインターへのポインター)
=> ポインターの値に変更されます。
したがって、ポイントに格納されている値(アドレスではなく)が a にコピーされます。
なぜこの種のコードが書かれているのかはまだわかりません。
あなたが投稿したコードはばかげています - 本当に完全ですか?
"point" と "a" はどちらもポインターです。
「a」は「point」に初期化されますが、「point」は完全に初期化されていません。呼び出し元が戻り値「a」を使用しようとすると、悪いことが起こります。
別の例を次に示します。
struct Point {
int x;
int y;
};
...
char * mem_alloc (int size)
{
return (char *)malloc (size);
}
...
Point *my_point = (Point *)mem_alloc (sizeof (struct Point));
...
このスニペットもばかげています...しかし、うまくいけば、あなたが見ているコードの背後にある理論的根拠を少し示しています...
の概念を見ると、malloc
常に割り当てられたメモリ空間のベース アドレスが返されます。malloc
関数の実際の構文は次のとおりです。
pointer_to_store_base_add_of_mem = (data_type_of_allocated_memory)malloc(size_of_array)
上記の例では、メモリの文字型を割り当てたため、(char*) を使用し、block_num で文字配列のサイズを指定し、ポイント ポインタは割り当てられたメモリのベース アドレスを格納します。