Skocz do zawartości

C++ Segmentation Fault


Andrzej Orkan

Rekomendowane odpowiedzi

W mojej klasie jest struktura:

 

struct stel // struktura elementu stosu

 

{

 

int lokator; // biezaca zawartosc elementu

 

struct stel *next; // wskaznik do nastepnego elementu

 

struct stel *prev; // wskaznik do poprzedniego elementu

 

} *p;

 

Klasa emuluje kolejke LIFO czyli stos. Nic w niej specjalnego - jak widać - nie ma. Teraz mam dwa obiekty - dajmy na to stos1 i stos2 - które są dwiema instancjami tej klasy. Na pewnym etapie chciałbym przeprowadzić operację taką (uwaga - wykonuję ją tylko wtedy gdy oba stosy są identyczne):

 

stos1.p = stos2.p;

 

To co prawda przynosi zamierzony efekt (stos1 przejmuje zawartość stosu2), ale po skompilowaniu (bez zastzreżeń) i wykonaniu programu (działa) mam komunikat "Naruszenie ochrony pamięci" - czyli segmentation fault. Ktoś mi odpowie czemu?

 

Pozdro, Orkan

 

P.S. Gdzie w necie mogę sobie DOKŁADNIE poczytać co to jest segmentation fault i kiedy zgrubsza się objawia? Please, jesli nie bardzo wiecie o co chodzi z moim programem :) to po prostu podeślijcie mi jakieś w miarę strawne info!

Odnośnik do komentarza
Udostępnij na innych stronach

Dawaj kod, sprobuje pomoc. [email protected]

 

Segmentation fault to proba nadpisania na pamiec do ktorej nie masz dostepu (nie zadeklarowales sobie miejsca) lub odczytu z tego typu pamieci.

 

Poza tym zamien linijki

 struct stel *next;
struct stel *prev;

na

 stel *next;
stel *prev;

bo mi tu smierdzi redeklaracja.

 

Pozdro,

buman

Odnośnik do komentarza
Udostępnij na innych stronach

Przesłałem Ci na maila okrojoną wersję programu i plików nagłówkowych. Tzn sam program zredukowałem tylko do użycia funkcji, która ten segmentation fault wywala. Jest to mianowicie funkcja reduce, której zadaniem jest zredukowanie dwóch identycznych obiektów typu stos do jednego obszaru pamięci z którego jednak nadal korzystają dwie zmienne.

 

Dzięki za jakieś wskazówki.

 

Orkan

Odnośnik do komentarza
Udostępnij na innych stronach

Siema!

 

Segmentation fault pojawia sie na koncu programu, wiec wiemy juz ze chodzi o destruktor. Wpisz sobie w cialo destruktora

cout<<"niszcze<<endl;

i wywolaj program bez funkcji reduce a pozniej z funkcja reduce. Moim skromnym zdaniem po przyrownaniu stos1.p = stos2.p wszystko gra ale przy opuszczaniu programu destruktor usuwa po kolei to na co wskazuje stos1.p a wiec usuwa stos2. Gdy przechodzi do usuwania stosu2, jego juz tam nie ma. Wiec odwoluje sie do pamieci ktorej juz nie ma ( signal 11 SIGSEV czyli segmentation fault(violation) ). Dlaczego przepisujesz wskazniki zamiast skaksowac od razu obiekt stos1? Nie bardzo rozgryzlem idee tego programu bo mnie mecza na uczelni jeszcze przed swietami, ale jak nadal nie bedziesz mogl nic zdziaalac to po wtorku sie znajde troche wiecej czasu.

 

Pozdrawiam,

buman

Odnośnik do komentarza
Udostępnij na innych stronach

Nie, nie chodzi o destruktor. Gdy w programie nie ma użytej funkcji reduce, to komunikatu nie ma, a przecież destruktor zadziała wiele razy. Tak więc jest to reduce i już to sprawdziłem i wątpliwości nie mam. Widzisz. Sam projekt opisuje klasę stosów obiektów dowolnego typu.

 

Funkcja reduce zapobiega tzw REDUNDANCJI czyli gdy podczas działania programu powstanie sobie jakiś stos identyczny z jakimś innym, który powstał wcześniej to na ten nowy już nie przydzielamy pamięci, tylko kasujemy mu pamięć (funkcja erase) i chcemy, żeby odtąd udawał on ten już wcześniej istniejący. To znaczy jeśli ten stary to A a ten nowo utworzony to B to gdy A==B, to reduce(B) i B = &A. Tak zgrubsza chciałbym żeby to działało.

 

To tyle jeśli chodzi o samą reduce. Rejestrowaniem wszystkich obiektów danego typu zajmuje się statyczna tablica rej[24], ale działanie w jej obrębie (funkcja regreduce) jest już przetestowane i jest OK.

 

Chodzi mi tylko o reduce. Czyli jakby konwersję stosu na wskaźnik do innego stosu. Czy to jest jasne? :) Jak mi rozwiążesz ten problem to normalnie stawiam ci browca :)))

 

Orkan

 

P.S. Dla uproszczenia zamiast głowić się nad strukturą mojej klasy przemyśl to dla dwóch liczb typu int. Na przykład mamy x=6. I nagle gdzieś później powstaje sobie y=6. Wtedy na skutek reduce(y,x) nasze x i y to odtąd będzie jeden i ten sam obiekt, choć inaczej nazywany. Czyli przekształcić x ze zmiennej typu int na jakby referencję na obiekt y. Pozdrawiam ;)

Odnośnik do komentarza
Udostępnij na innych stronach

Nie zrozumielismy sie, przeczytaj to uwaznie! Blad segmentacji wywoluje destruktor (ktory jest dobrze napisany - nie mam w nim bledow, powtarzam destruktor jest ok!) ktory glupieje po uzyciu funkcji reduce. Wyobraz sobie 6 pudelek na polce, z kazdego pudelka zwisa sznurek. Ten sznurek to wskaznik poczatku stosu. Gdy wywolujesz funkcje reduce(3,4) to oprozniasz podelko 3 z zawartosci, doklejasz do tego pudelka dodatkowy sznurek ktory laczy je z pudelkiem nr 4. I teraz zobacz co jest grane : Ida destruktory i ciagna

1)sznurek 1 - pudelko 1 spada, wszystko git

2)sznurek 2 - pudelko 2 spada, wszystko git

3)sznurek 3 - pudelko 3(puste w srodku po erase) spada I POCIAGA ZA SOBA PUDELKO 4, nadal wszystko git

4)sznurek 4 - zaraz, zaraz, gdzie jest sznurek 4 i pudelko 4, przeciez napisali na poczatku programu ze bedzie pudelko nr 4, chyba sie im cos pomylilo, SEGMENTATION FAULT

 

Sorry ze to jest napisane w taki beznadziejny sposob ale ja naprawde musze Cie zmusic zebys zrozumial co chce Ci przekazac:) Na 99% to wlasnie dlatego masz blad segmntacji. Destruktory usuwajac pusty obiekt X, usuwa od razu powiazany z nim obiekt Y - za jednym zamachem. Pozniej chce usunac Y (bo w ciele programy byla deklaracja Y) i dobiera sie do pamieci ktora jest pusta i jest SIGSEV czyli blad segmentacji. Wlacz debuggera jakiegos to zobaczysz gdzie jest blad.

 

P.S. Moja rada - usuwaj caly obiekt zamiast kasowac jego zawartosc i przepisywac wskazniki, albo chociaz powiedz czemu nie mozesz tak zrobic to moze uda sie to jakos inaczej obejsc

Pozdrawiam,

buman

 

Juz mialem to skonczyc bo jest pozno w nocy ale usiadlem i looknalem na Twoj destruktor, on robi to samo co funkcji erase, wiec po wpisaniu

blabla::~destruktor{
 erase(*this);
 delete p;
 liczba--;
}

Blad segmentacji zniknal, moze to jest drapanie sie prawa reka po lewym uchu i wcale nie ma sensu ale ja juz nie mysle bo umieram ze zmeczenia, powowdzenia. Moj destruktor naprawde dziala ;) Pozdro

Odnośnik do komentarza
Udostępnij na innych stronach

  • 3 weeks later...

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
×
×
  • Dodaj nową pozycję...