0

私はいくつかのメモリを持っており、いくつかの部分に割り当てようとしています。だから私はリンクされたリストを持っています。各ノードは、割り当てられたメモリのサイズと次のノードを追跡します。

リクエスターにポインターを返すときは、このノードが終了した直後にポインターを返します (return newNode + sizeOf(node) など)。これは、リクエスターが必要とするのは使用するメモリだけだからです。

問題は、ノードを変更して解放しようとしたときです。myFree がポインターで呼び出され、ノードに到達するために pointer - sizeOf(node) を実行すると、機能しません。

私は何を間違っていますか?

私はそれが役に立つとは思わないが、ここにいくつかのコードがあります:

#define HEADER(24)
printf("Original pointer %-10p\n", pointer);
head *toUse = pointer + HEADER;
printf("Pointer to memory to be used %-10p\n", toUse);
printf("Trying to read the header again %-10p\n", toUse - HEADER);

1 番目と 3 番目の printf では、異なるアドレスが返されます。それが問題です。

テストに関しては、最初にメモリを1つ割り当てただけで、まだ機能しません。

4

3 に答える 3

1

C では、(pointer + n)は ... と同等&pointer[n]です。つまり、インデックスは、バイトではなく、ポインターが指す項目をカウントします。バイト オフセットが必要な場合は、 を使用します((char*)pointer + n)。しかし、あなたの場合、バイトオフセットは必要ありません。それ以外の

return newNode + sizeof(node);

あなたはただすることができます

return newNode + 1;

また

return &newNode[1];

(void*)ただし、呼び出し元が任意の型として使用できる何かへのポインターを返す場合は、おそらくそれらをキャストしたいと思うでしょう。(void*)ポインターから元のノードに戻るには、(node*)vp - 1またはを使用します(node*)((char*)vp - sizeof(node))

また、

#define HEADER(24)

関数のようなマクロに似ているため、コンパイルできません。マクロ名と左括弧の間に少なくとも 1 つのスペースが必要です (または括弧を省略します)。

于 2012-10-11T18:46:25.177 に答える
1

問題を解決するのに十分なコードが提供されていません。しかし、私は推測することができます。

の宣言を見せてくださいpointer。私はそうではない head *pointer;と推測しています。ポインター演算では、ポインターの型が考慮されます。

(たとえば)ポインターに追加1すると、ポインターはバイト単位intでインクリメントされます。1 * sizeof intタイプがそうであれば、バイト単位shortでインクリメントされます。1 * sizeof short必ずしも同じとは限りません。

したがって、pointeris (再び、たとえば) として宣言されている場合、char *pointerそれに追加HEADERすると、ポインターがHEADER( 24) バイトずつインクリメントされます ( sizeof charis always であるため1)。ただし、タイプが であるHEADERから後で減算すると、バイト単位で減分されます。繰り返しますが、同じではありません。toUsehead*HEADER * sizeof head

于 2012-10-11T17:59:08.523 に答える
0

ここで確認するためにさらにコードを使用できます...しかし、これはあなたに任せます。あなたが言った:

have some memory and I try to allocate it in several pieces. So I have a linked list. Each node keeps track of the size the allocated piece of memory is and the next node.

だから私はあなたがノードを作成していると推測していますmalloc()

ptr_to_next_node = ptr_to_current_node+sizeof(node);

まあ、それはうまくいきません。リンクされたリストは連続したメモリではないため、ポインター演算を行うことはできません。ポインター演算が配列で機能する理由は、取得するメモリが連続するためです。

 char array [0][1][2][3]
             ^  ^  ^  ^
             |  |  |  +----------0x86C00004
             |  |  +-------------0x86C00003
             |  +----------------0x86C00002              
             +-------------------0x86C00001

 linked_list 

    +-------+        +-------+        +-------+
    | node1 |        | node2 |        | node3 |
    | next---------->| next---------->| next---------->NULL
    +-------+        +-------+        +-------+
    (0x86C0001)      (0x86C000A)      (0x86C00BC)

わかりましたので、メモリ内の値はあまり意味をなさないかもしれませんが、ここで説明しようとしている点がわかります。配列はsizeof(type)互いに離れており、ノードに割り当てるメモリはほとんどどこにでもある可能性があります。オフセットを追加することはできませんnext

前後にジャンプできるようにしたい場合は、ポインタを前方nextおよび後方に追加する必要がありますprev

于 2012-10-11T19:24:04.643 に答える