falscherptr problem



  • Oh Oh ... kann es sein das das der Fehler ist? Ich weiße dem ptr keinen Wert zu?

    also wie gesagt bin ja noch Frisch in dem Thema und ich weiß jetzt nicht genau wie ich das bewerkstelligen muss das ich dem ptrBuch einen Wert zuweise... ich dachte das wenn ptrBuch->name zeigt das er dann den Wert aus Name nimmt?

    Meine Struktur Buch:

    struct buch{
    	int buchnummer;
    	char name[64];
    	char autor[64];
    	verleih *letzteAusleihe;//
    	//...
    };
    

    Dort steckt ja name drinne und so dachte ich das :

    neuerartikel[i].artikeldaten.ptrBuch->name
    

    dann halt auf den Buchnamen zeigt ... sich den Buchnamen rausholt ... Falsch gedacht?



  • Nein, das wäre Münchhausen- Methode, sich an den eigenen Haaren aus dem Sumpf zu ziehen.
    Du mußt jede Adresse initialisieren. Üblicherweise erhältst Du da den Pointer per malloc.
    Also struct Buch alleine ist ja nur die Beschreibung, wie das aussieht, aber noch kein echter Speicher, ebensowenig wie der Pointer darauf.



  • Ja, falsch gedacht! 😉

    Wenn du einen Zeiger vom Typ buch erzeugst, dann ist das halt erstmal nur ein Zeiger vom Typ buch. Das heißt aber noch nicht, dass er auch auf gültigen Speicher zeigt.

    buch MeinBuch;
    buch *pBuch=&MeinBuch;  //hier würde pBuch auf MeinBuch zeigen und du könntest mit pBuch->name auf das Element zugreifen. pBuch selbst enthält aber nur die Adresse, nichts weiter.
    
    buch *pBuch2;  //dieser Zeiger zeigt noch nirgendwo hin.
    

    In deinem Fall würde ich mal sagen, dass ein Zeiger unnötig ist, oder? erzeuge einfach eine normale Instanz der Struktur buch in artikel.





  • _matze schrieb:

    Ein wenig Lektüre zum Thema gibt's hier:

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-124532-and-sid-is-d52fd8c501b2fd34da0da8c5f0017c81.html

    Werd ich mir mal antun heute ABend "also die Lektüre 😉 " ...

    So also die Deklaration der Struktur hab ich ja (nur nicht mitkopiert):

    buch neuesbuch[10];
    

    jetzt muss also noch der Pointer deklariert werden?

    daten *ptrBuch = &neuesbuch
    

    ?



  • Virokams schrieb:

    buch neuesbuch[10];
    
    daten *ptrBuch = &neuesbuch
    

    ?

    Das dürfte nicht klappen. Wenn, dann so:

    daten *ptrBuch = neuesbuch;
    

    Aber ob das so alles sinnvoll ist...

    Zeig am besten mal ein wenig mehr Code. Konnte z.B. ja keiner ahnen, dass neuesbuch ein Array ist... 😉



  • Virokams schrieb:

    So also die Deklaration der Struktur hab ich ja (nur nicht mitkopiert):

    buch neuesbuch[10];
    

    du müsstest übrigens noch 'struct' davor schreiben. 'buch' ist ja kein typedef bei dir.
    beispiel:

    struct buch
    {
       ...
    };
    
     ...
     buch b; // error
     struct buch b; // so geht's
     ...
    

    🙂



  • +fricky schrieb:

    du müsstest übrigens noch 'struct' davor schreiben. 'buch' ist ja kein typedef bei dir.

    Ist bestimmt mit nem C++-Compiler erstellt...



  • _matze schrieb:

    ...

    Zeig am besten mal ein wenig mehr Code. Konnte z.B. ja keiner ahnen, dass neuesbuch ein Array ist... 😉

    Ok also hier die ganzen relevanten Code ausschnitte:

    Struct.h:

    #pragma once
    
    #include <stdio.h>
    #include <tchar.h>
    #include "stdafx.h"
    
    struct verleih;
    
    struct dvd{
    	int dvdnummer;
    	char dvdname[64];
    };
    
    struct buch{
    	int buchnummer;
    	char name[64];
    	char autor[64];
    	verleih *letzteAusleihe;//
    	//...
    };
    
    struct artikel{
    	int artikelnummer;
    	int artikelart;//0 ist nicht definiert 1 DvD 2 Buch
    
    	union daten{
    		dvd * ptrDvd;
    		buch * ptrBuch;
    	}artikeldaten;
    	verleih * ptrAusleihe;
    };
    
    struct kunde{
    int kundennummer;
    char name[64];
    //...
    };
    
    struct verleih{
    buch *vbuch[10];
    kunde *vkunde;
    //...
    };
    

    artikel.cpp:

    #include "stdafx.h"
    #include "struct.h"
    #include <stdio.h>
    #include <string.h>
    #include "artikel.h"
    
    struct buch neuesbuch[10];
    struct dvd neuedvd[10];
    struct artikel neuerartikel[20] = { 0 };
    
    void clearbuf()
    {
        setvbuf(stdin,NULL,_IONBF,0);
        setvbuf(stdin,NULL,_IOFBF,BUFSIZ);
    } 
    
    void artikel_anzeigen()
    {
    	int i;
    	neuerartikel[0].artikeldaten.ptrBuch = NULL;
    
    	for (i=0; i<10; i++)
    	{
    		if(neuerartikel[i].artikeldaten.ptrBuch->name != '\0' )
    			printf("Buchname:'%s'\n",neuerartikel[i].artikeldaten.ptrBuch->name);
    		else if (neuerartikel[i].artikeldaten.ptrBuch->name != '\0' && i<1)
    		{
    			printf("Keine Buecher in der Bibliothek \n");
    			break;
    		}
    	}
    }
    
    //Buchdeklaration
    void Testbuchdaten()
    {
    	strcpy(neuesbuch[0].name,"Harry Potter");
    	strcpy(neuesbuch[0].autor,"Joanne K. Rowling");
    	neuesbuch[0].buchnummer = 0;
    
    //....... viele mehr
    
    }
    

    mehr ist eigentlich nicht wichtig würde ich sagen.
    Wenn ich erstmal weiß wo der Fehler bei der Anzeige der Artikel ist wird mir das erstellen von Artikeln vielleicht auch klarer 🙂

    als zusatz Artikel_erstellen():

    void artikel_anlegen()
    {
    	int i = 0;
    	int j = 0;
    	int z = 0;	
    
    	for (j = 0; j>20; j++)//Artikelnummer bestimmen ... leeren platz finden
    	{
    		if ( neuerartikel[j].artikeldaten.ptrBuch->name != '\0' )
    		{
    			neuerartikel[j].artikelnummer = j;
    			break;
    		}
    	}
    
    	printf("Welche Art von Artikel soll hinzugefuegt werden?\n1 DvD\n2 Buch\n");
    	scanf("%d",&neuerartikel[neuerartikel[j].artikelnummer].artikelart);
    
    	if ( neuerartikel[neuerartikel[j].artikelnummer].artikelart == 1 )
    	{
    		printf("bla");
    		return;
    		//DvD anlegen
    	}
    	else if ( neuerartikel[neuerartikel[j].artikelnummer].artikelart == 2 )
    	{
    
    		for(i=0; i<10; i++)
    		{
    			if ( neuerartikel[i].artikeldaten.ptrBuch->name[0] == '\0')
    			{	 
    				printf("Bitte Buchnummer angeben:\n");//Buchnummer
    				scanf("%d",&neuerartikel[i].artikeldaten.ptrBuch->buchnummer);
    
    				clearbuf(); 
    				printf("Bitte Buchnamen eingeben:\n");//Buchname
    				gets(neuerartikel[i].artikeldaten.ptrBuch->name);
    
    				clearbuf();
    				printf("Bitte Buchautor angeben:\n");//Buchautor
    				gets(neuerartikel[i].artikeldaten.ptrBuch->autor);
    
    				for(int j=0; j<i; j++)//Durchlauf der Buchnummern
    				{	//Keine Buchnummer darf doppelt sein!
    					if(neuerartikel[i].artikeldaten.ptrBuch->name == neuerartikel[j].artikeldaten.ptrBuch->name)
    					{
    						printf("Die Buchnummer ist schon in verwendung. ");//
    						neuerartikel[i].artikeldaten.ptrBuch->autor[j] = '\0';
    						neuerartikel[i].artikeldaten.ptrBuch->name[j] = '\0';
    						neuerartikel[i].artikeldaten.ptrBuch->buchnummer = '\0';
    						z=1;
    						break;
    					}
    				}
    				if(z>0)//Z>0 wenn Buchnummer vorhanden dann wird kein Buch ausgeliehen 
    				{
    					printf("Es wurde kein Buch hinzugefuegt!\n");
    					break;
    				}
    				else//Buch wird hinzugefügt
    				{
    					printf("BNr:%d Name:'%s' von '%s' wurde angelegt!\n"); 
    					getchar();
    					break;
    				}
    			}
    		}
    		// Buch anlegen
    	}
    	else if ( neuerartikel[neuerartikel[j].artikelnummer].artikelart > 2 || neuerartikel[neuerartikel[j].artikelnummer].artikelart < 1 )
    	{
    		printf("Nichtdefinierte Eingabe! Bitte 1 fuer DvD oder 2 fuer Buch eingeben!");
    		return;
    	}
    }
    


  • Ein paar grundlegende Tipps:

    Deine structs global in struct.h anzulegen, halte ich nicht für so gut. Warum sind das nicht z.B. lokale Variablen der main, die du dann als Parameter an die Funktionen übergibst, die auch was damit machen?

    buch sollte einfach ein Member von artikel sein. Ich verstehe nicht ganz, warum ein neuer Artikel auf ein Element eines ansonsten unabhängigen buch-Arrays zeigen sollte. Mach es doch einfach so, dass jeder Artikel halt eine Struktur enthält, in der du Namen, Autor usw. ablegst.

    Wenn du einen neuen Artikel anlegen willst, dann ist diese Schleife, um festzustellen, welches Element noch nocht gefüllt wurde, nicht so optimal. Halte z.B. einfach in einer Variablen fest, wieviele Elemente bereits hinzugefügt wurden.

    Ich würde mich ärgern, wenn ich ständig komplette Bücher eingeben würde, nur um im Anschluss dann gesagt zu bekommen, dass die Buchnummer (also die erste Eingabe) falsch war, weil schon vorhanden, und alle Eingaben verworfen werden. 😉 Außerdem überschreibst du alle gemachten Eingaben dann mit 0. Sinnvoller wäre es, es gar nicht soweit kommen zu lassen. Eingabe der Nummer in eine temporäre Variable, wenn gültig dann weitermachen. Noch sinnvoller wäre es, die Buchnummer automatisch fortlaufend zu vergeben (es sein denn, du willst, dass Lücken entstehen dürfen).

    Sowas hier

    for (j = 0; j>20; j++)
    

    geht nicht. In die Schleife springt er nie rein. j wird mit 0 initialisiert, die Bedingung ist aber "mache weiter, solange j>20 ist". Sie ist also nie erfüllt. Du meinst vermutlich j<20.

    Es macht ein wenig den Eindruck, dass du versuchst, all deine Ideen in einem Rutsch ins Programm zu quetschen, und dabei vielleicht ein klein wenig die Übersicht verlierst. 🙂 Versuche einfach, strukturierter zu programmieren und dich Stück für Stück 'ranzutasten. Z.B. könntest du erst mal mit den Büchern anfangen. Und wenn das steht und perfekt läuft, dann kannst du die DVDs und das ganze Verleihen hinzufügen.



  • ^^und falls das keine übung für structs und pointer-auf-structs, etc. sein soll, sondern ein programm, dass irgendwann mal wirklich benutzt wird, dann nimm 'ne richtige datenbank dafür, mySQL oder sowas.
    🙂



  • +fricky schrieb:

    ^^und falls das keine übung für structs und pointer-auf-structs,

    Glaube ich schon, daher...

    +fricky schrieb:

    nimm 'ne richtige datenbank dafür, mySQL oder sowas.

    Nö, lieber erstmal nicht. Denn wenn das erstmal alles steht, hat er einiges kapiert. Dann ist man schlauer und kann immer noch über eine "richtige" Lösung mit 'ner Datenbank nachdenken. 🕶



  • jau die for schleife ist schon korrigiert... natürlich hab ich mich verschrieben.

    also deine Tipps sind grundlägend natürlich total richtig. "Problem" an der Sache ist das es vorgaben vom Ausbilder sind. also Wenn da jetzt etwas nicht soooo prickelnd ist ... soll es so bleiben weil es meinem Ausbilder grundsätzlich um die Arbeit mit Ptr geht. Ich soll das halt lernen ... übern ... das Programm war ja schon fertig von mir geschrieben... als zusatzübung wurde jetzt noch die Struct Artikel mit der enthaltenen Union gemacht.

    also tut mir leid wenn ich 2 Beiträge später immer noch den "unschönen" Code vorzeigen muss aber ich lasse ihn jetzt erstmal so wie er ist und versuche nur weiter mit Ptr was zu machen (Wie auch meine Frage war wo denn jetzt mein Fehler liegt das er mir schlechterptr anzeigt... bzw das ich auf einen fremden Speicher zugreife).

    also komme ich nochmal zurück und sage schonmal Danke natürlich nehme ich mir die Tipps zu herzen :)!

    wenn ich es also schaffe den ptr vernünftig auf einen Speicher zu deklarieren dürfte kein fehler kommen das er auf einen Fremden Speicher zugreift?



  • Virokams schrieb:

    wenn ich es also schaffe den ptr vernünftig auf einen Speicher zu deklarieren dürfte kein fehler kommen das er auf einen Fremden Speicher zugreift?

    Jo! Entweder, du weist dem Pointer eine gültige Adresse zu (von einer Variablen, die bereits existiert, wie in meinem Beispiel vorhin), oder du forderst mit malloc speicher an, in den du dann schreiben darfst. In letzterem Fall darfst du aber nicht das free vergessen, dass den Speicher wieder freigibt (sonst produzierst du ein Speicherleck).



  • gut soweit verstanden ... zur Syntax:

    union daten *ptrBuch = NULL;

    geht nicht...

    neuerartikel[0].artikeldaten.ptrBuch = NULL;

    hatte ich auch probiert... geht auch nicht...

    hääh? -.-



  • Virokams schrieb:

    union daten *ptrBuch = NULL;
    geht nicht...

    benutze einen richtigen C compiler (z.b. indem du deine files von .cpp in .c umtaufst), dann geht's
    🙂



  • +fricky schrieb:

    Virokams schrieb:

    union daten *ptrBuch = NULL;
    geht nicht...

    benutze einen richtigen C compiler (z.b. indem du deine files von .cpp in .c umtaufst), dann geht's
    🙂

    edit: äääh, achso, in einer struct-definition darfste natürlich auch keine zuweisungen machen, falls du das versuchen solltest.
    🙂



  • nene war jetzt in meiner Methode void artikel_anzeigen() definiert.

    von .cpp in .c macht er bei mir nicht... dann kompiliert er garnicht ?!...

    muss das ? oder kann ich nicht auch einfach anders Null definieren und gut is?



  • Virokams schrieb:

    also aus .cpp .c machen... ok mal probieren.

    wahrscheinlich werden dann andere stellen angemeckert (z.b. wenn du nackte struct-tagnamen als typen verwendest). aber da musste jetzt durch, wenn du in C programmieren willst. du könntest dich auch in's c++ forum verschieben lassen, nur befürchte ich, dass sich dort niemend deiner fragen annehemn wird. stattdessen werden sie dir 'designfehler' vorhalten, 'boost' empfehlen usw. so wie man's kennt.
    🙂



  • +fricky schrieb:

    wahrscheinlich werden dann andere stellen angemeckert (z.b. wenn du nackte struct-tagnamen als typen verwendest). aber da musste jetzt durch, wenn du in C programmieren willst.

    Und ich glaube nicht, dass bei dem Umfang wirklich viele Anpassungen gemacht werden müssen. Mit den typedefs isses wahrscheinlich schon fast erledigt...


Anmelden zum Antworten