指针+ int与点 - int

时间:2012-10-11 17:40:54

标签: c memory pointers

我有一些记忆,我试着将它分成几块。 所以我有一个链表。每个节点都会跟踪分配的内存块和下一个节点的大小。

当我将指针返回给请求者时,我会在此节点结束后立即返回一个指针(例如返回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给了我不同的地址。这就是问题所在。

至于测试,我只是在开头分配一块内存,它仍然无效。

3 个答案:

答案 0 :(得分:1)

您没有给我们足够的代码来解决问题。但是,我可以猜一猜。

向我们展示pointer的声明。我猜它是不是 head *pointer;。指针算法将指针的类型考虑在内。

当您(例如)将1添加到指向int的指针时,指针会增加1 * sizeof int个字节。如果类型为short,那么它将增加1 * sizeof short个字节。不一定是同一件事。

因此,如果pointer(例如)再次声明为char *pointer,则向其添加HEADER会使指针增加HEADER24) 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