【问题标题】:Using std::ptrdiff_t on user defined types在用户定义的类型上使用 std::ptrdiff_t
【发布时间】:2015-03-01 18:00:14
【问题描述】:

我有一个名为 node 的简单结构,它包含一个值 + 2 个指向下一个/上一个节点的指针。

template <class T>
struct node {

     node<T> *prev = NULL;
     node<T> *next = NULL;
     T data;        
};

这里我们有在末尾添加一个新节点的函数。

void push_back( T val ) {           

    node<T> *n = new node<T>;   // create node to hold val
    n->data = val;              // set node data with val

    if ( node_count == 0 ) {     

        begins = n;             // begins points to first node          
    }
    else{

        ends->next = n;         // set next in ends
        n->prev = ends;         // set previous             
    }

    ends = n;                   // update ends
    node_count++;               // update list size
}                                       

在 main 中,我们创建了 100 个链接节点,每个节点都有一个唯一的 int 值。

for (int i = 0; i != 100; i++){  push_back(i); }

这里是指向第一个/最后一个节点的指针:

node<T> *begins; 
node<T> *ends; 

当尝试应用指针算法时,麻烦就开始了:

std::ptrdiff_t node_sum = ends - begins;

不知何故 node_sum == 528,如果我进行 x32 编译,则 node_sum == 781。

为什么 node_sum 不是 100 ?

【问题讨论】:

  • 这段代码能编译吗?在push_back 函数中没有beginend,除非你将它们设为全局。
  • 不保证单独的节点在列表中的位置;第一个节点可能位于第二个之前和第三个之后。 ptrdiff_t 类型用于将两个指针之间的差异放入有保证的连续内存中,这意味着两个指针指向单个数组中的位置(或数组末尾之外的一个元素)。其他任何事情都会导致未定义的行为;任何结果都是可能的,而且都是正确的。
  • @Shan:发布的代码无法编译,但源代码可以编译,我删除了相关部分以使其更容易阅读。

标签: c++ ptrdiff-t


【解决方案1】:

您的节点不是数组的一部分。它们分别被分配在内存分配器可以为它们找到的任何位置。您不能减去它们并期望任何特定值。事实上,这样做是未定义的行为。为了计算链表中节点之间的距离,您需要按照 next 或 prev 指针对其进行迭代。

【讨论】:

    【解决方案2】:

    请记住,分配不必是连续的,即使您在彼此相邻的地方进行分配。

    这意味着如果你有例如

    begin = new node<T>;
    end = new node<T>;
    

    不保证beginend 会相邻。

    您只能对指向同一内存区域的指针(如数组)使用指针算法,否则您将出现未定义的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-31
      • 1970-01-01
      • 2014-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多