【问题标题】:Pointer + int vs point - int指针 + int 与点 - int
【发布时间】:2012-10-11 17:40:54
【问题描述】:

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

当我将指针返回给请求者时,我会在该节点结束后立即返回一个指针(比如 return newNode + sizeOf(node)),因为请求者只需要使用内存。

问题是当我尝试通过更改节点来释放它时。当使用指针调用 myFree 并且我执行指针 - 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);

第一个和第三个 printf 给了我不同的地址。这就是问题所在。

至于测试,我一开始只分配了一块内存,还是不行。

【问题讨论】:

  • 如果你在几个块中分配,你的块可能不相邻,所以pointer-sizeof(node)不一定会把你放在前一个节点的开头。
  • 我认为这不是有效的 C,#define 是错误的。
  • @Mat:不是,HEADER(24)之间需要一个空格。
  • 你不懂指针运算。 pointer + HEADERtoUse - HEADER 会根据 toUse 和指针的类型有不同的结果。显示定义这些类型的代码。

标签: c memory pointers


【解决方案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】:

    您没有为我们提供足够的代码来解决问题。不过,我可以猜测一下。

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

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

    因此,如果pointer (再次,例如)声明为char *pointer,则将HEADER 添加到它会使指针增加HEADER (24) 个字节(因为sizeof char 始终是@987654334 @)。但是,当您稍后从toUse(类型为head*)中减去HEADER 时,它会减少HEADER * sizeof head 字节。同样,不是同一件事。

    【讨论】:

      【解决方案3】:

      可以在这里使用更多代码来确定......但我将把它扔给你。你说:

      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()'ing 他们一些内存,然后尝试做类似的事情:

      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

      【讨论】:

      • 是的,我明白了。我没有使用 malloc,但我的指针是不同的类型。我能够修复它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-26
      • 1970-01-01
      • 2021-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-07
      相关资源
      最近更新 更多