C++ Listenprogramm stürtzt trotz erfolgreichen Kompilierens ab

Docci

Grünschnabel
Ich wünsche euch erstmal einen schönen Tag, ich bin neu hier und dies wird mein erster Beitrag, habt also etwas Nachsicht mit mir :)

Kurze Einleitung:
Also ich (eigentlich war es eine Gruppenarbeit) habe aus einer Auffgabenstellung herraus ein Programm geschrieben das diesem Standardbeispiel "Listen" zugeordnet werden kann. Es soll eine Liste erzeugen, Knotenpunkte ablaufen, einfügen, löschen etc pp. Dadurch wurde mein Interesse für C++ geweckt, so dass ich Privat versuche mir etwas mehr beizubringen und mich zurzeit mit dem Thema Modularisierung/Objektorientierte Programmierung beschäftige.

Das Problem:
Das Programm habe ich also versucht zu Modularisieren, sprich das Programm in funktionen und header zu zerlegen. Im großen und ganzen klappt das auch, nur das ich irgendwann beim Kompilieren die Meldung "multiple defination of..." erhielt. Diese Fehlermeldung konnte ich abschalten, nun stürtzt das Programm nach geringer Zeit ab, was mich langsam zur Verzweiflung bringt, da auch eine Fehlersuche keine Ergebnisse bringt.

Darum bitte ich das sich das Programm mal jemand anschaut und mir Hilfestellung geben kann.(Programm ist als .dev-Projekt geschrieben)

ListenMain.cpp: // Main
Code:
#include <stdio.h>
#include <stdlib.h>
#include "ListenHead.h"

//#include "listen_l.h"
//struct Listenknoten *l_kopf=NULL;                                                    //Listenkopf erzeugen(1.2.1) 
//struct Listenknoten *l_ende=NULL; 

int main(int argc, char* argv[])                                                //Main mit Parameterübergabe 
{

struct Listenknoten *l_kopf=NULL;                                                    //Listenkopf erzeugen(1.2.1) 
struct Listenknoten *l_ende=NULL;                                                    //Listenende

	l_kopf=new Listenknoten();
	l_kopf->l_next=NULL;
	l_ende=new Listenknoten();
	l_ende->l_next=NULL;;
	
	
	
}

ListenFkt.cpp // Funktionen
Code:
#include <stdio.h> 
#include "ListenHead.h"

#include "listen_l.h"

//------------------------------------------------------------------------------// 1. addFirtst()
void addFirst(int inhalt)                                                       // fügt einen Knoten am Anfang der Liste an
{
              //Inhalt der "Funktion"

 }
////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------// 2. getFirtst()
int getFirst()                                                                  // gibt den Inhalt des ersten Knotens zurück
{
	//Inhalt der "Funktion"
}
////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------// 3. removeFirtst()
int removeFirst()                                                               // entfernt den ersten Knoten UND setzt den Zeiger des Listenkopfes auf den Nachfolger
{
                   //Inhalt der "Funktion"
}
////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------// 5. getLast()
int getLast() // gibt den Inhalt des letzten Knotens zurück
{
	//Inhalt der "Funktion"
}
////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------// 6. removeLast()
int removeLast()                                                                // entfernt den letzten Knoten UND setzt den Zeiger des VORLETZTEN Knotens auf NULL
{			                                                                	// Aufwand O(n), weil er alle Knoten durchlaufen muss und sich den VORLETZTEN Knoten merken muss <=> bei einfachverketteten Listen
	
}
////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------// 7. removeDVListe()
int removeDVListe()
{
	return 0;
}
////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------// 9. 
void insert(int inhalt)                                                         // durchläuft die Liste von hinten und fügt neuen Knoten vor nächst kleinerem Element ein
{
	struct Listenknoten * tmp_listenknoten=new Listenknoten();
	tmp_listenknoten->l_inhalt=inhalt;                                          //den übergebenen Inhalt in einen neuen Knoten gespeichert
	tmp_listenknoten->l_next=NULL;
	if(l_kopf->l_next==NULL)	
	{
		l_kopf->l_next=tmp_listenknoten;
		l_ende->l_next=tmp_listenknoten;
	}else
	{
		struct Listenknoten * letzter_knoten=new Listenknoten();                //temporärer Speicherplatz zum austauschen
		letzter_knoten=l_kopf->l_next;

		while(letzter_knoten->l_next!=NULL && letzter_knoten->l_next->l_inhalt<inhalt)
		{
			letzter_knoten=letzter_knoten->l_next;
		}

		
	
		tmp_listenknoten->l_next=letzter_knoten->l_next;
		letzter_knoten->l_next=tmp_listenknoten;

	}
}

ListenHead.h // sollte eigentlich einzige Header sein, durch "multple..." Problem und anderen Erfahrungen das "Problemkind" "ausgelagert"
Code:
// Variablendeklaration

void addFirst(int);
int getFirst();
int removeFirst();
void addLast(int);
int getLast();
int removeLast();
void insert(int);
void printOutListe();

// Struct

struct Listenknoten                                                             //Typdefinition eines Listenelementes mit Inhalt, Verweis auf benachbarte Elemente
{
	int						l_inhalt; //Listeninhalt vom Typ Integer 
	struct Listenknoten *   l_next;	  //Verweis (Referrenz/Pointer) auf das nachfolgende Listenelement


};

// Problemkind; Diese beiden erzeugen da sie in der fkt.cpp und in der main verwendet werden die "multiple declaration"

// struct Listenknoten *l_kopf=NULL;                                                    //Listenkopf erzeugen(1.2.1) 
// struct Listenknoten *l_ende=NULL;

listen_l.h // Hilfsheader--> "multiple...."-Problem
Code:
struct Listenknoten *l_kopf; //Listenkopf erzeugen(1.2.1) 
struct Listenknoten *l_ende; //Listenende

Ich verwende den DevCompiler Version 4.9.9.2, das Programm ist so wie es ist die "Absturz"-Variante. Lässt sich aber ohne Fehler Kompilieren

Mit freundlichen Grüßen

Docci

edit: bissl was entfernt
 
Zuletzt bearbeitet:
Hi und Willkommen bei tutorials.de :)

Ich vermute einmal, als du noch den Compilerfehler (war es ein Linkerfehler?) bekommen hast, hast du l_kopf und l_ende in der listen_l.h gemacht, damit du überall darauf zugreifen kannst?
Und wegen dem Fehler hast du herumprobiert, das du ihn wegbekommst, und hast jetzt mehrere verschiedene Variablen mit dem gleichen Namen.
Du erwartest aber natürlich den Wert von einer in jeder mit dem Namen, und da liegt das Problem.

Lösung:
Nimm noch einmal die Compilerfehler-Variante und entfern die Variablen aus der .h-Datei.
Dafür machst du sie in einer .cpp-Datei (nur einer!).
In allen anderen .cpp-Dateien, in denen du die zwei Variablen benötigst, schreibst du sie mit extern an.

So:
C++:
extern struct Listenknoten *l_kopf;
extern struct Listenknoten *l_ende;
Nur in einer einzigen cpp ohne extern. zB da, wo auch main ist.

Gruß
 
Erst mal vielen Dank das sich überhaupt jemand mein Problem angeschaut hat.

Hi Docci,
zu einfach und doppelt verketteten Listen gibts im Web unglaublich viel Material. Das ist so eine typische Datenstruktur, die in der Lehre immer wieder durchgekaut wird. Du wirst eine Implementation in fast jeder Sprache finden.
Mit schönen Bildchen zum Beispiel hier: http://perlgeek.de/de/artikel/einfach-verkettete-listen

Gruß, Traveller

Ich habe keine Probleme mit dem Schreiben von Listen, ich glaube du hast dir mein Programm nicht richtig angeschaut oder mich missverstanden, die Liste an sich als einzel Programm in einer .cpp funktioniert ja :)
Hi und Willkommen bei tutorials.de

Ich vermute einmal, als du noch den Compilerfehler (war es ein Linkerfehler?) bekommen hast, hast du l_kopf und l_ende in der listen_l.h gemacht, damit du überall darauf zugreifen kannst?
Und wegen dem Fehler hast du herumprobiert, das du ihn wegbekommst, und hast jetzt mehrere verschiedene Variablen mit dem gleichen Namen.
Du erwartest aber natürlich den Wert von einer in jeder mit dem Namen, und da liegt das Problem.

Lösung:
Nimm noch einmal die Compilerfehler-Variante und entfern die Variablen aus der .h-Datei.
Dafür machst du sie in einer .cpp-Datei (nur einer!).
In allen anderen .cpp-Dateien, in denen du die zwei Variablen benötigst, schreibst du sie mit extern an.

So:
Code cpp:

1
2



extern struct Listenknoten *l_kopf;
extern struct Listenknoten *l_ende;

Nur in einer einzigen cpp ohne extern. zB da, wo auch main ist.

ich freue mich das du mein Problem erkannt hast, und danke dir für den Hinweis (funktioniert jetzt übrigens das ganze wie ich das will). Hatte zwar schon mit extern herumprobiert, was ich so im Internet gefunden habe, aber leider passt ein Fall nicht auf den anderen. Es ist immer gut wenn ein aussenstehender sich das ganze mal anschaut und einen handfesten Hinweis liefert. Vielen Dank nochmal :)

Ein glücklicher

Docci

ps: um ein hirnloses kopieren zu unterbinden ohne sich über Listen gedanken gemacht zu haben werde ich den Code etwas "stutzen" aber soviel beibehalten das der Fehler erkennbarbar bleibt.
 
Da hast du mich erwischt, ich habe mir deinen Code wirklich nicht genauer angeschaut, sorry. Liegt aber daran, dass es bei mehr als 10 Zeilen Code in Arbeit ausartet. Das Forum ist da, um ein paar Tips und Anregungen zu geben und kleine Fehler zu beheben. Die gängigen Algorithmen und Datenstrukturen findest du incl. Implementierung im Web oder in jedem Buch zu dem Thema. Das A&D-Buch von N. Wirth bekommt man gebraucht für <5€, das ist eins der wenigen Bücher, das man mal komplett durchlesen sollte.

Einen kleinen Tip hab ich aber noch für dich. In der C++ STL gibt es die Klasse List. Wie die implementiert ist, kannst du dir auch anschauen. Den Quellcode bekommt man auf http://www.sgi.com/tech/stl/download.html. Dort wird viel mit Templates gearbeitet, der Code ist aber sehr sauber und verständlich.

Schönes WE, traveller
 
Zurück