EDIT: Я думаю, что мой вопрос полностью отличается от предлагаемого дубликата. Он спрашивает об общем случае, в то время как мой вопрос задает очень конкретный случай, когда причина для странного поведения должна быть прослеживаемой, учитывая, насколько она конкретна.Функция ввода в дважды связанном списке произвольно указывает на элемент заголовка после вызова pop()
У меня есть действительно странное поведение в моей двойной реализации LL. В принципе, если я pop()
(с головы) элемент и , тоinject()
(добавить в хвост) какой-то другой элемент, который последний элемент хвоста теперь указывает на голову списка, по-видимому, без причины (я предполагаю вместо NULL по умолчанию или хотя бы случайный адрес).
Я понял, как исправить проблему. При инъекции я не указывал «следующий» нового узла на NULL.
Однако я все же хотел бы понять, почему инжектируемый узел решил указать на голову без конкретного направления, где указывать.
Эффект заключается в том, что если я перемещаю список, начиная с головы (но не начинаю с хвоста), я продолжаю зацикливаться навсегда, так как последний элемент хвоста указывает на начало списка.
EDIT: Так что я попытался распечатывания адрес, указатель, указывающий только после вызова таНос в inject()
, и по какой-то сумасшедшей причине указатель создано уже указывает на адрес голова; но это происходит только в том случае, если я вызываю pop()
перед вызовом inject()
. Невероятно странно ...
int pop()
{
node* temp = head;
int value = temp->value;
head = temp->next;
free(temp);
head->previous = NULL;
size--;
return value;
}
void inject(int value)
{
if (tail == NULL)
{
tail = malloc(sizeof(node));
tail->value = value;
tail->next = NULL;
tail->previous = NULL;
head = tail;
size++;
}
else
{
node* new_node = malloc(sizeof(node));
printf("pointing to: %p\n", new_node->next);// points to head after pop() call
new_node->value = value;
tail->next = new_node;
new_node->previous = tail;
tail = new_node;
//new_node->next = NULL;
size++;
}
}
Закомментированный из линии в Inject() решает эту проблему, но до сих пор не объясняет, почему хвост будет указывать обратно на голову, если я впрыснуть после поп-музыки.
Ниже приведен код, прежде чем основной() в случае, если:
typedef struct node{
int value;
struct node* next;
struct node* previous;
}node;
node* head = NULL;
node* tail = NULL;
int head_value();
int tail_value();
void push(int);
int pop();
void inject(int);
int eject();
int size = 0;
Это называется Неопределенное поведение. Если переменная неинициализирована, она может содержать любое (полу) случайное значение. Нет смысла пытаться точно понять, как это произошло. Результат непредсказуем и может меняться в зависимости от компилятора, параметров компилятора, окружающего кода, погоды и т. Д. – kaylum
Возможный дубликат [Does «Undefined Behavior» действительно разрешает \ * что-нибудь \ * произойти?] (Http://stackoverflow.com/questions/32132574/does-undefined-behavior-really-permit-anything-to-happen) – kaylum
@kaylum, конечно, я понимаю это, но ясно, что это не может быть совпадением, что это указывает на руководитель списка; если бы это было действительно случайное распределение, вероятность была бы невероятно мала. Поэтому должна быть веская причина, почему она указывает на голову конкретно, и я уверен, что причина прослеживается. –