我有一些记忆,我试着将它分成几块。 所以我有一个链表。每个节点都会跟踪分配的内存块和下一个节点的大小。
当我将指针返回给请求者时,我会在此节点结束后立即返回一个指针(例如返回newNode + sizeOf(node)),因为请求者只需要使用内存。
问题是当我尝试通过更改节点来释放它时。当使用指针调用myFree并且我执行指针 - sizeOf(节点)以到达节点时,它不起作用。
我做错了什么?
我不认为它有用,但这里有一些代码:
#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);
第一个和第三个printf给了我不同的地址。这就是问题所在。
至于测试,我只是在开头分配一块内存,它仍然无效。
答案 0 :(得分:1)
您没有给我们足够的代码来解决问题。但是,我可以猜一猜。
向我们展示pointer
的声明。我猜它是不是 head *pointer;
。指针算法将指针的类型考虑在内。
当您(例如)将1
添加到指向int
的指针时,指针会增加1 * sizeof int
个字节。如果类型为short
,那么它将增加1 * sizeof short
个字节。不一定是同一件事。
因此,如果pointer
(例如)再次声明为char *pointer
,则向其添加HEADER
会使指针增加HEADER
(24
) bytes(因为sizeof char
总是1
)。但是,当您稍后从类型为HEADER
的{{1}}中减去toUse
时,它会减少head*
个字节。同样,不一样。
答案 1 :(得分: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)
将无法编译,因为它类似于函数式宏;在宏名称和左括号之间至少需要一个空格(或省略括号)。
答案 2 :(得分: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
。