Использование 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?

1

Решение

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

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

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

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

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

3

Другие решения

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

4

По вопросам рекламы [email protected]