Stack-Liste stürzt am Ende ab

drpingoo

Erfahrenes Mitglied
Hallo zusammen,

ich hätte da 3 Fragen zu einem Programm, das ich soeben geschrieben habe. Meiner erste Frage ist, wo bei mir in der Listenverknüpfung der Fehler ist? Weil immer wenn ich das letzte Element poppe, beendet das Programm mit einem Fehler.

Die anderen 2 Fragen sind eher allgemeiner Natur. Ich dachte ursprünglich, dass wenn man einem Pointer nichts zuweist, sei der NULL? Nun, das dachte ich eben, aber das hat er dann bei der if(top==NULL)-Abfrage (siehe Code) nicht verstanden, deshalb habe ich den Pointer schliesslich explizit mit NULL in der Fkt. init() deklariert, dann funktionierts.

Und die 3. Frage wäre, wieso ich das first nicht deleten kann. Ich dachte eigtl, dass wenn 2 Poniters, in diesem Falle top und first, auf dasselbe Element zeigen, dann wäre es egal, wenn ich einen Pointer löschen würde, weil ja immer noch der andere auf das Element zeigt.

lg
drpingoo

C++:
#include <stdlib.h>
#include <iostream>
#include <string>
using namespace std;


//Structs, Arrays und andere globale Variablen hier definieren.

struct liste{
	int value;
	liste *next;
} ;


liste *top = new liste;

int counter;




void init() {

	top=NULL;//2. Frage
}



void push(int element){

	
	if(top==NULL){

		//top->value=element;
		liste *first = new liste;//2. Frage
		first->value=element;
		top=first;
		//delete first; //3.Frage
		cout << "top->value: " << top->value << endl;
	}
	else{

	liste *list = new liste;
	liste *temp = new liste;
	list->value=element;
	temp=top;
	list->next=temp;
	top=list;
	cout << "top->value: " << top->value << endl;
	}

	counter++;

}

int size() {


	return counter;
}

int pop(){

	
	if(size()!=0){
		liste *tmp = new liste;
		tmp=top;
		cout << "top->value: " << top->value << endl;
		if(top->next!=NULL){
			top=top->next;}
		counter--;
		return top->value;
}
	else{

		cout << "Die Liste ist leer" << endl;
		return -1;
	
	}

	return top->value;
}

void clear() {
	while(size()!=0){
		pop();
	}

}


//Dieses Funktion implementiert eine Testumgebung fr den Stack
void test() {
    cout << "The program has been startet without any arguments." << endl;
    cout << "The program enters the stack test mode:" << endl;
    cout << "Enter one of the commands: push, pop, end" << endl;
    string command;
    do{
      cin >> command;
      if (command == "pop"){
        cout << pop() << endl;
      } else if (command == "push"){
        cout << "element?";
        int elementToPush;
        cin >> elementToPush;
        push(elementToPush);
      } else if(command == "end"){
        clear();   		
      } 
	  
	  else if(command == "size"){
		 cout << size() << endl;
	  }
	  
	  else {cout << "command not recognised"<< endl;};
    }while(command != "end");
}

int main(int argc, char * argv[]){

  init();	
  test();
  clear();
  return 0;

}
 
so zur 2ten frage soviel: mit zeiger verhält sich das genau wie mit variablen da es eigentlich ja auch welche sind und sie müssen genau so extra auf etwas bestimmtes gesetzt werden so kann es passieren das irgendein bullshit dort drin steht und bei zeiger kannst du dir auch sehr schön etwas wichtiges im arbeitsspeicher zerschießen.

zu 3. wenn du einen zeiger mit delete löschst dann löschst du ja nicht nur den zeiger sondern auch alles was in der speicheradresse des zeigers steht somit hast du dann kein elemt mehr worauf dein aderer zeiger zeigen kann, weil da nichts mehr im speicher steht oder schon wieder etwas anderes von einem anderen programm.
 
HI

wenn du einem Pointer noch nichts zugewiesen hast, zeigt er wie gesagt auf nichts sinnvolles, aber er wird nicht automatisch auf NULL gesetzt.
NULL bedeutet zwar, das er auf nichts zeigt, aber sobald du den Pointer deklariert hast solltest du ihn selber auf NULL setzten.
Und nach sachen wie free/delete etc machst du das am besten auch selber, bin mir nicht sicher ob die das tun.
Dann weißt du wenigstens sicher, das dein Pointer immer NULL ist, wenn er nirgendwo hin zeigt.

Und ein Pointer merkt sich ja nur immer, WO bestimmte Werte stehen, die Werte selber haben mit ihm Überhaupt nichts zu tun.
dH wenn du die Werte von einem Pointer freigibst und noch einen anderen Pointer auf die gleiche Stelle hast, sind die Werte trotzdem weg

gruß
 
Hallo,

du musst sowohl "top" als auch "counter" initialisieren. Bei C++ erfolgt keine Initialisierung bei der Deklaration; es stehen zufällige Werte in der Variablen. Nimm besser "0" statt "NULL", weil letzteres nicht portabel ist. Die Zuweisung kannst du auch gleich bei der Deklaration erledigen. dann sparst du dir in init-Funktion.

In deinem Code legst du mit "new" ständig neue Listen an. Dadurch entsteht irgendwelcher Zeigerkuddedelmuddel, der wohl auch zum Absturz führt (ich hab's nicht genauer analysiert). Du brachst nur ein einziges "new" nei push und gar keins bei "pop". Dafür wird bei "pop" ein "delete" benötigt, denn schließlich musst du den reservierten Speicher wieder freigeben.

So sollte es besser funktionieren (ungetestet :-) ):
C++:
liste *top    = 0;
int   counter = 0;

void push(int element)
{
    if( top == 0 )
    {
        top = new liste;
        top->value = element;

        std::cout << "top->value: " << top->value << std::endl;
    }
    else
    {
        liste *list = top;
        
        top = new liste; 
        top->value = element;
        top->next  = list;

        std::cout << "top->value: " << top->value << std::endl;
    }
 
    counter++;
}

int pop()
{
    int nResult = (-1);

    if( size() != 0 )
    {
        nResult = top->value;
        liste *tmp = top;
        top = top->next;
        
        delete tmp;
    }
    else
    {
         std::cout << "Die Liste ist leer" << std::endl;
    }
 
    return nResult;
}
Gruß
MCoder
 
Danke Leute!

Jetzt funktionierts, der Fehler lag iwo in der pop-Fkt. Weiss zwar auch nicht genau wieso, wenn ich den Code betrachte, vermutlich weil ich den Speicherplatz nicht freigegeben habe, aber dann sollte es eigtl nur Memory-Leaks geben, naja.. auf jeden Fall ts jetzt.

Ah ok, kapiert, dann verhält sich das deleten extremer, als wenn ich nur einen Pointer umhenken würde.

@MCoder Wieso kann man top auf 0 setzen, ist doch ein Pointer, deswegen gibts doch den Begriff NULL dachte ich, und was meinst du mit portabel?

Lg
 
@MCoder Wieso kann man top auf 0 setzen, ist doch ein Pointer, deswegen gibts doch den Begriff NULL dachte ich, und was meinst du mit portabel?
Ein Pointer ist eine Variable die einen numerischen Wert speichert, der aber als Speicheradresse interpretiert werden muss. NULL ist ein Makro, dass dieser Variable die 0 (im hoffentlich richtigen Form) zuweist. Zum Thema Portabilität ist folgender Link ganz interessant. Dort heißt es:
The constant NULL is known to cause trouble on some platforms due to different word sizes and stricter compilers.
Gruß
MCoder
 
Ok, also, wenn ich das richtig verstanden habe, bedeutet portabel, dass der Code, wenn er portabel ist, ohne Probleme auch auf anderen Betriebssystemen läuft.

Und bei der Initialisierung von Pointern auf NULL/0 muss ich einfach bei Klassen aufpassen, so wie ich jetzt das aus dem Text entnommen habe.

Danke:)
mfg
drpingoo
 
Nja daaaan macht ihr was anderes als ich beim protieren ... hab damit noch 0 probleme gehabt, dafür das es so bekannt sein soll ...
 
Zurück