Pointer..



  • @Wutz sagte in Pointer..:

    Wow. Da wird was generiert. Das erklärt auch den unsinnigen Code.
    Und du erwartest jetzt, dass wir rätseln, was der Generator generiert?!

    Naja, den Thread habe ich mit dem Inhalt geöffnet, wie man sich Pointer am Besten verinnerlichen kann.
    Dann kam von dir "ohne Kontext keine sinnvolle Hilfe", was ich verstehen kann.
    Dann poste ich den Code und erklär was Sache ist. Jede weitere Antwort fand irgendwas schlect am generierten Code.

    Wenn jemand mir sagen kann wie ich im ersten Beitrag die Funktion zum laufen kriege ohne einen Speicherzugriffsfehler zu erhalten. Und da ich mit Ponter immer noch nicht ganz warm bin, dachte ich frage Experten.

    Edit:
    Ich habe mal ein Beispiel gemacht um das alles etwas zu verstehen (auch mit erzeugten Code). Und das funktioniert tatdellos. Auch die erste Funktion(initw) in meinem Skript funktioniert tadellos. Also am Generator liegts nicht. Er kann ineffizient sein, aber das ist mir ziemlich egal, da ich die Aufgabe löse(hoffen wirs mal), dem Prof die schicke und dann in nem halben Jahr ohne weitere Nutzung lösche. Also der Code vom Generator funktioniert.



  • @werdas_34 sagte in Pointer..:

    Und das funktioniert tatdellos.

    Das kannst du als Anfänger nicht beurteilen - glaube mir, den Satz habe ich hier schon hundertmal gesagt, und er ist unbestritten, denn nur weil du keinen Fehler erhältst und das Programm mit deinen Spieldaten die von dir erwarteten Ergebnisse bringt, ist das Programm noch lange nicht korrekt.
    Deinen Fehler kann man nicht nachvollziehen, solange man den Aufrufkontext deine dynamischen Funktionsargumente nicht kennt, dazu gibt es u.a. Debugger.
    Du greifst auf undefinierten Speicher zu, also entweder ist dein definierter (unsinnig als globales Array definiert) Speicher zu klein oder dein Index zu groß.



  • Ich starte Server und Client.
    Client fragt mich nach einer Eingabe:
    I
    Client gibt aus Database initialized to empty.
    Serverseitig wird ausgegeben: Client called initw
    Ich gebe beim Client ein: i ash
    Server gibt ash aus wenn printf auskommentiert ist und dann Speicherzugriffsfehler.

    Es kann icht daran liegen das das Wort zu groß ist oder ähnliches.

    Hier mal die rdbase.h, wo weitere Sachen definiert sind:

    #ifndef _RDBASE_H_RPCGEN
    #define _RDBASE_H_RPCGEN
    
    #include <rpc/rpc.h>
    
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #define DBASESIZE 100
    #define MAXWORD 50
    #define MAXRESULT 10
    #define MAXSUCHERG 100
    
    struct upd {
    	char *upd_old;
    	char *upd_new;
    };
    typedef struct upd upd;
    
    struct oneword {
    	char *word;
    };
    typedef struct oneword oneword;
    
    struct manywords {
    	struct {
    		u_int words_len;
    		oneword *words_val;
    	} words;
    };
    typedef struct manywords manywords;
    
    struct twoargs {
    	char *firstarg;
    	char *secondarg;
    };
    typedef struct twoargs twoargs;
    
    #define RDBASEPROG 0x30090949
    #define RDBASEVERS 1
    
    #if defined(__STDC__) || defined(__cplusplus)
    #define INITW 1
    extern  int * initw_1(void *, CLIENT *);
    extern  int * initw_1_svc(void *, struct svc_req *);
    #define INSERTW 2
    extern  int * insertw_1(char **, CLIENT *);
    extern  int * insertw_1_svc(char **, struct svc_req *);
    #define DELETEW 3
    extern  int * deletew_1(char **, CLIENT *);
    extern  int * deletew_1_svc(char **, struct svc_req *);
    #define LOOKUPW 4
    extern  int * lookupw_1(char **, CLIENT *);
    extern  int * lookupw_1_svc(char **, struct svc_req *);
    #define UPDATEW 5
    extern  int * updatew_1(upd *, CLIENT *);
    extern  int * updatew_1_svc(upd *, struct svc_req *);
    #define COUNTW 6
    extern  int * countw_1(void *, CLIENT *);
    extern  int * countw_1_svc(void *, struct svc_req *);
    #define SELECTW 7
    extern  char ** selectw_1(void *, CLIENT *);
    extern  char ** selectw_1_svc(void *, struct svc_req *);
    #define SELECTBETWEENW 8
    extern  manywords * selectbetweenw_1(twoargs *, CLIENT *);
    extern  manywords * selectbetweenw_1_svc(twoargs *, struct svc_req *);
    extern int rdbaseprog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
    
    #else /* K&R C */
    #define INITW 1
    extern  int * initw_1();
    extern  int * initw_1_svc();
    #define INSERTW 2
    extern  int * insertw_1();
    extern  int * insertw_1_svc();
    #define DELETEW 3
    extern  int * deletew_1();
    extern  int * deletew_1_svc();
    #define LOOKUPW 4
    extern  int * lookupw_1();
    extern  int * lookupw_1_svc();
    #define UPDATEW 5
    extern  int * updatew_1();
    extern  int * updatew_1_svc();
    #define COUNTW 6
    extern  int * countw_1();
    extern  int * countw_1_svc();
    #define SELECTW 7
    extern  char ** selectw_1();
    extern  char ** selectw_1_svc();
    #define SELECTBETWEENW 8
    extern  manywords * selectbetweenw_1();
    extern  manywords * selectbetweenw_1_svc();
    extern int rdbaseprog_1_freeresult ();
    #endif /* K&R C */
    
    /* the xdr functions */
    
    #if defined(__STDC__) || defined(__cplusplus)
    extern  bool_t xdr_upd (XDR *, upd*);
    extern  bool_t xdr_oneword (XDR *, oneword*);
    extern  bool_t xdr_manywords (XDR *, manywords*);
    extern  bool_t xdr_twoargs (XDR *, twoargs*);
    
    #else /* K&R C */
    extern bool_t xdr_upd ();
    extern bool_t xdr_oneword ();
    extern bool_t xdr_manywords ();
    extern bool_t xdr_twoargs ();
    
    #endif /* K&R C */
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* !_RDBASE_H_RPCGEN */
    

    dict wird mit [100] [51] initialisiert.
    In der Funktion wird dict[0] mit argp überschrieben, da nwords anfangs 0 ist. Da durch den printf bekannt ist das argp den richtigen Wert hat und dict[0] ist ja definiert.

    Ich sehe jetzt nicht wo der Speicher zu klein bzw der Index zu groß sind. Kannst du das erläutern?



  • Deine Ausgabe ist fehlerhaft:

    for(int k = 0; i<nwords; k++){
    	for(int l = 0; i<MAXWORD; l++){
    		printf("%s\n", dict[k][l]);
    	}
    }
    

    Du gibst einzelne Zeichen als String aus (denn dictist wohl als char-Array deklariert und nicht als char*-Array, denn sonst würde der Code darüber [strcmp, strcpy] keinen Sinn machen).
    Ändere es also zu

    for(int k = 0; i<nwords; k++){
    	printf("%s\n", dict[k]);
    }
    


  • @Th69 sagte in Pointer..:

    Deine Ausgabe ist fehlerhaft:

    Vielen Dank. Das ist nur ein Versuch gewesen die Datenbank auszulesen, ob die Werte richtig verwendet werden.

    Ich habe vergessen das auszukommentieren. Vielen Dank für die Korrektur.

    Dennoch löst es das Problem leider nicht.



  • @werdas_34
    Hi ich gehe immer noch davon aus, dass dein strcpy dein Problem ist.
    Ich denke an dieser Stelle wird dein Speicher korrumpiert.

    Warum ich danke, habe da so ein Gefühl!



  • @pmqtt sagte in Pointer..:

    Warum ich danke, habe da so ein Gefühl!

    bitte.



  • Gern geschehen danke denke alles das gleiche



  • @pmqtt sagte in Pointer..:

    Hi ich gehe immer noch davon aus, dass dein strcpy dein Problem ist.
    Ich denke an dieser Stelle wird dein Speicher korrumpiert.

    Ich wollte wissen ob der Fehler danach kommt, oder vor dem strcpy. Also printf vor und nach der Funktion reingesetzt.
    Gemerkt er gibt beides aus. Dann wieder die offensichtlich unsinnigen Pointer beim Rückgabewert hinzugefügt und es funktioniert. Ich verstehe zwar nicht ganz was ich jetzt groß anders hatte am Anfang. Aber ok.

    Hier mal die funktionierende Funktion(Aufruf usw ist alles gleich geblieben):

    int *
    insertw_1_svc(char **argp, struct svc_req *rqstp)
    {
    	static int  result;
    	printf("%s\n", *argp);
    
    	int i;
    	for (i=0; i<nwords; i++)
    		if (strcmp (*argp, dict[i]) == 0)
    			return 0;
    	printf("Test 1\n");
    	strcpy(dict[nwords], *argp);
    	printf("Test 2\n");
    	printf("%s\n", dict[nwords]);
    	nwords++;
    	result = nwords;
    	
    	return &result;
    }
    
    


  • @Wutz sagte in Pointer..:

    Da du den Aufrufkontext verheimlichst, kann dir keiner helfen - was soll die Funktion überhaupt machen?



  • @werdas_34 sagte in Pointer..:

    Und wieder merke ich das ich Pointer noch nicht ganz verinnerlicht habe.

    Ich verstehe zwar nicht ganz was ich jetzt groß anders hatte am Anfang. Aber ok.

    Und was hat das Gefrickel dir nun gebracht? Nichts.
    Du hast immer noch keine Ahnung von Pointern und weißt nicht, warum dein Programm abstürzt.
    Da bist du auch nicht besser als die Leute, die nach Lektüre der Pfuscher-JW Online-Sinnfreiartikeln hier aufschlagen und behaupten, sie hätten Pointer verstanden und nur noch eine kleine Frage hätten.



  • Allen frohe Ostern und bleibt gesund.

    @werdas_34 sagte in Pointer..:

    Hier mal die funktionierende Funktion(Aufruf usw ist alles gleich geblieben):

    int *
    insertw_1_svc(char **argp, struct svc_req *rqstp)
    {
    	static int  result;
    	printf("%s\n", *argp);
    
    	int i;
    	for (i=0; i<nwords; i++)
    		if (strcmp (*argp, dict[i]) == 0)
    			return 0;
    	printf("Test 1\n");
    	strcpy(dict[nwords], *argp);
    	printf("Test 2\n");
    	printf("%s\n", dict[nwords]);
    	nwords++;
    	result = nwords;
    	
    	return &result;
    }
    

    Ein paar Fragen an Dich, da dieser Code so nicht kompiliert.

    • Was sind nwords und dict? Es müssen globale Variable sein. Weshalb sind sie global definiert?
    • Der Klassiker in C, weshalb wird int als Typ für eine Zählvariable gewählt für etwas, was dynamisch alloziert wurde? ints können insbesondere auf 64Bit Plattformen nicht den kompletten Wertebereich von dynamisch allozierten Feldern abdecken. Es gibt dafür size_tund ssize_t.
    • Was für einen Grund hat es den Rückgabewert als lokale statische Variable zu deklarieren und dann per Zeiger zurückzugeben?
    • Weshalb wird argp als ** übergeben? Was für einen Zweck erfüllt das?


  • @werdas_34
    Füge mal bitte folgendes ein:

    int *
    insertw_1_svc(char **argp, struct svc_req *rqstp)
    {
    	static int  result;
    	printf("%s\n", *argp);
    
    	int i;
    	for (i=0; i<nwords; i++)
    		if (strcmp (*argp, dict[i]) == 0)
    			return 0;
    	printf("Length of argp:%d \n",strlen(*argp));
            printf("Space in dict on position nwords:%d",sizeof(dict[nwords]));
    	strcpy(dict[nwords], *argp);
    	printf("Test 2\n");
    	printf("%s\n", dict[nwords]);
    	nwords++;
    	result = nwords;
    	
    	return &result;
    }
    

    und verrate uns mal bitte die zwei Zahlen die herraus kommen


Anmelden zum Antworten