Zgłoszono wyjątek: naruszenie dostępu do odczytu. **curr** było 0xDDDDDDDD.: wystąpił wyjątek

0

Cześć,
próbuje zrobić algorytm tworzący listę jednokierunkową i usuwający co drugi jej element, k razy. Visual Studio wywala mi wyjątek o treści:

"Zgłoszono wyjątek: naruszenie dostępu do odczytu.
curr było 0xDDDDDDDD."

w funkcji deleteK w lini 37, o treści: curr = curr->next;

Czy ktoś może ma pomysł jak to naprawić?

Z góry dzięki za pomoc :)

#include <iostream>
using namespace std;

struct Node {
	int data;
	Node* next;
	Node(int x)
	{
		data = x;
		next = NULL;
	}
};

void printList(Node* head)
{
	if (head == NULL)
		return;
	Node* temp = head;
	do {
		cout << temp->data << "->";
		temp = temp->next;
	} while (temp != head);
	cout << head->data << endl;
}

Node deleteK(Node** head_ref, int k)
{
	Node* head = *head_ref;

	Node *curr = head, *prev, *lastK = head;
	while (k > 0) {

		printList(head);

		for (int i = 0; i < 2; i++) {
			prev = curr;
			curr = curr->next;
		}

		if (curr == head) {
			prev = head;
			while (prev->next != head)
				prev = prev->next;
			head = curr->next;
			prev->next = head;
			*head_ref = head;
			lastK = curr;
			free(curr);
			k--;
		}

		else if (curr->next == head) {
			prev->next = head;
			lastK = curr;
			free(curr);
			k--;
		}
		else {
			prev->next = curr->next;
			lastK = curr;
			free(curr);
			k--;
		}
	}
	return *lastK;
}

void insertNode(Node** head_ref, int x)
{
	Node* head = *head_ref;
	Node* temp = new Node(x);

	if (head == NULL) {
		temp->next = temp;
		*head_ref = temp;
	}

	else {
		Node* temp1 = head;
		while (temp1->next != head)
			temp1 = temp1->next;
		temp1->next = temp;
		temp->next = head;
	}
}

int main()
{
	int m;
	cin >> m;
	for (int i = 0; i < m; i++)
	{
		int n, k;
		cin >> n;
		cin >> k;
		struct Node* head = NULL;
		for (int j = 1; j <= n; j++)
			insertNode(&head, j);
		cout << deleteK(&head, k).data << endl;
	}

	return 0;
}
0

Mieszasz new i free(). Jak używasz new to musisz zwolnić za pomocą delete. Jak używasz malloc() - wtedy użyj free().

    do {
        cout << temp->data << "->";
        temp = temp->next;
    } while (temp != head);

Jak nie masz cyklu to jest to pętla nieskończona, a więc UB.

Node deleteK(Node** head_ref, int k)

Nicniemówiąca nazwa funkcji. Czym jest K? Poza tym, dlaczego funkcja usuwająca [cośtam] wywołuje printList? Zwracanie Node też jest trochę podejrzane.

0

1

**curr było 0xDDDDDDDD
**

Kompilator w wersji debug wypełnia (może wypełniać) niezainicjowane przez ciebie zmienne szczególną wartością, na przykład 0xDD, po te żeby błędy były bardziej wyraziste i powtarzalne.

Bardzo to w stylu C zrobiłeś, proceduralnie. Powinieneś mieć klasę MyList, a wynalazki typu
Node head_ref**
powinny być w klasie (składowe). proceduralne funkcje staną się metodami itd.
Wtedy czytelność i bezpieczeństwo bardzo zyska

1 użytkowników online, w tym zalogowanych: 0, gości: 1