Co jest z tym NULL-em?

0

Witam ;)

W ramach podróży (i nauki) po C++ śmignąłem sobie w 20 minut listę dwukierunową.
Lecz (może 20 minut to za mało) jedna z metod nie chce działać.

Mianowicie ta:

//metoda ta ma za zadanie ustawić wartość obiektu na żądaną
//a w razie gdyby obiekt nie istniał, stworzyć go i ustawić wartość
template<class X>
void List<X>::Set(Uint Node, X Value)
{
	LIST_NODE<X>* It = NodeStart;
	Uint I = 1;
	for(; I <= Node; I++)
	{
		It = It->NextNode;
	};
//dotąd jest git
//pewnie dostanie słowne lanie, za to, że to wolna metoda przechodzenia po elementach jest ;)
//lecz tu
	if(It->Value == NULL)  //w tym warunku jest jakiś błąd
                                       //Skoro It->Value nie jest zainicjowany
                                       //To jest NULL przecież
                                       //A on przesakuje do else
                                       //I powoduje błąd naruszenia
		It->Value = new X(Value);
	else
		*It->Value = Value;
};

I teraz pytanie: Co mógłbym z tym zrobić?

0

Skoro warunek nigdy nie jest spełniony, to najprawdopodobniej nie nullujesz wskaźnika Value, albo gdzieś piszesz po adresie na który on wskazuje. Odpal debbuger i sprawdź co tam siedzi w tym Value.

0

W C++ nie istnieje "nie zainicjalizowanych" wartości jeżeli wartość nie zainicjalizujesz to zawiera jakieś śmieci.
NULL to ((void*)0) - definicja rodem z C, nie powinna być używana w C++. W C++ dla kompatybilności definicja została z tym że zmieniono ją na samo 0.

0

Value jest 0xcdcdcdcd, czyli nie zainicjowany.

0

Sory, że pod moim postem:)

Heh, widocznie źle zrozumiałem rozdział o wskaźnikach :p

Czyli w metodzie (ew. konstruktorze, jeżeli tworzy on ileś elementów) dodającej nowe elementy najpierw muszę wyczyścić te śmieci, wyzerować,
a potem mogę sobie spokojnie ten warunek usprawnić i tworzyć (w razie potrzeby) obiekty o żądanej wartości. Dobrze rozumiem?

0

Tak.

0

NULL to ((void*)0) - definicja rodem z C, nie powinna być używana w C++.

NULL to (void*)0 ale w C.
w C++ NULL to po prostu 0.

Co do tego „nie powinna być używana” — masz jakiś inny pomysł, jeśli nullptr jest niedostępne?

0
if(It->Value == NULL) 

A gdzie sprawdzenie, czy It != NULL ?
Jeżeli It == NULL to nic szczególnego, że Ci się wykrzacza program :)

if(It != NULL) 
if(It->Value == NULL) 
0

Sądze ,że w twoim programie jest jakiś błąd logiczny. Załóżmy ,że zdefiniowałeś określoną liczbę węzłów. Np 10. Do każdego węzła oczywiście przypisałeś następny węzeł. A na co pokazuje ostatni węzeł?
void List<X>::Set(Uint Node, X Value)
Załóżmy ,że wywołałeś tą funkcję z pierwszym parametrem wynoszącym sto. Zastanów jak zachowa się pętla przez którą iterujesz po węzłach. Jak dotrze do ostatniego elementu( jest to 10 element) to NextNode wskaże nieprawidłową wartość a pętla dalej będzie iterować. Ja bym zrobił tak zdefiniował określoną liczbę wezłów(wszystko bym połączył) do ostatniego węzła do NextNode wpisałbym wartość zerową. Następnie w tej pętli for zrobiłbym tworzenie węzła. Dałbym warunek:

if(!It->NextNode) //znaczy ,że jesteśmy przy ostatnim elemencie
//w tym momencie do NextNode przypisałbym nowy węzeł i przypisałbym do niego podaną wartość po czym instrukcją break wyszedł bym z pętli 
0

Powinno być:

for(; I <= Node; I++)
{
  if (It->NextNode != NULL)
    It = It->NextNode;
  else
    throw std::runtime_error("brak elementu");
}    

To tak na dobry początek.
Poza tym oczywiście przy dodawaniu obiektów/struktur node trzeba robić inicjalizację:

newNode->NextNode = NULL;

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