Использование std::ptrdiff_t для пользовательских типов

У меня есть простая структура с именем 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
}                                       

В основном мы создаем 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?

2 ответа

Решение

Помните, что распределение не обязательно должно быть последовательным, даже если вы делаете распределение прямо рядом друг с другом.

Это означает, что если у вас есть, например,

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

не гарантируется, что begin а также end будет рядом друг с другом.

Вы можете использовать арифметику указателей только для указателей, которые указывают на одну и ту же область памяти, например массив, иначе у вас неопределенное поведение.

Ваши узлы не являются частью массива. Каждый из них выделяется отдельно в любом месте, которое может найти для них распределитель памяти. Вы не можете вычесть их и ожидать какую-то конкретную ценность. Фактически, это неопределенное поведение. Чтобы посчитать расстояние между узлами в вашем связанном списке, вам нужно выполнить итерацию по нему, следуя указателям next или prev.

Другие вопросы по тегам