was bedeutet dieser funktionsrumpf (pointer)



  • vielleicht versucht die Funktion getToken den Inhalt von delimiters zu verändern, "XY" ist aber ein Stringliteral und somit konstant, d.h. du kann den Inhalt nicht verändert (sonst gibt es sowas wie segfault). Am besten du liest dir genauer die Dokumentation über deine getToken Funktion durch.



  • Erst einmal danke für alle Antworten 🙂

    @zeh mau
    du hast recht, in der tat wird der string, auf den buf zeigt in der funktion geändert. ich habe das jetzt so angepasst wie du es sagtest, habe aber noch immer einen segmentation fault.

    ich sage euch jetzt mal, was getToken() macht, dann könnt ihr damit mehr anfangen:

    Sie nimmt den String, auf den buf zeigt, und scannt ihn in einer for-schleife stellenweise (&buf[x]) nach dem String ab, der als letzter Parameter übergeben wurde. In meinem Beispiel also "XY". Dann bricht er die Schleife ab.

    Dann kopiert er alles, was in dem String, auf den buf zeigt, und was VOR dem "XY" steht, in den String, auf den das übergebene "*token" zeigt.

    Gleichzeitig wird genau dieser Teil aus dem buf-String gelöscht.
    Dies ist ja jetzt eigentlich möglich, weil ich das eben entsprechend zeh mau's tipp verändert habe.

    Hier die Implementierung ('delimiter' wäre z.B. "XY"):

    int getToken(char *token, char *buf, int *buflen, char delimiter[3]) {
        int i;
    
        /* buf is too short to contain token, shortest token is delimiter */
        if (*buflen < 2)
            return -1;
    
        /* search buf for token-delimiter */
        for (i = 0; i < *buflen -1; i++) {
            if (strncmp(&buf[i],delimiter,2)!=0)
                token[i] = buf[i];
            else break;
        }
    
        /* if token not followed by delimiter, return error */
        if ((strncmp(&buf[i], delimiter,2)!=0)) {
            token[0] = '\0';
            return -1;
        }
        /* null-terminate token and remove the found token from buf */
        else {
            token[i] = '\0';
            memmove(buf, &buf[i+2], BUFSIZE-(i+2));
            *buflen -= i+2;
            return 1;
        }
    }
    

    Was mir beim Test aufgefallen ist:
    die Funktion getToken() gibt 1 zurück. (habe ich mir printen lassen)

    DANACH gibt sie einen segmentation fault ! also irgendwie seltsam ?!

    woran könnte es noch liegen?
    mein String-Pointer 'token' ist ja jetzt auch keine Konstante, also
    sollte er da doch auch reinschreiben können?
    Habe ich die Speicheralloziierung davon vielleicht falsch gemacht oder so?

    danke soweit schon mal 👍



  • int main(void)
    {
       char strbuf[] = "hallo";
       char * pctoken;
    
       int ilaenge;
    
       // 4
       ilaenge = strlen(strbuf);
    
       // abschließendes '\0' vergessen??
       pctoken = malloc(sizeof(ilaenge)+1);
    
       printf("%d",getToken(pctoken,strbuf,&ilaenge,"XY"));
    
       free(pctoken);
    
       getchar();
    
       return 0;
    }
    

    Schau mal, ob du hiermit weiterkommst???



  • funktioniert leider nicht.
    noch immer genau das selbe. mein konsolen-output:

    Übergebener String: hallo
    Rückgabewert von getToken(): 1
    Segmentation fault
    

    wieso returned die funktion 1, aber kriegt danach nen speicherzugriffsfehler?



  • erstmal sorry, ich kann nicht editieren weil ich nicht eingeloggt war...

    noch ein paar überlegungen / infos meinerseits:

    also erstmal ist mein beispiel vom letzten beitrag schmarrn.

    in diesem fall returned sie NICHT '1' sondern '-1', was daran liegt,
    dass der String "hallo" eben das Token "XY" nicht enthält.

    wenn ich aber "halloXY" daraus mache, returned die funktion '1'.

    d.h. ja eigentlich, wenn man sich die funktion mal ansieht, dass
    sie auch die hilfsfunktion "memmove()" erfolgreich aufruft und den
    String verändert.

    ich denke, es liegt an folgendem Block in der funktion:

    /* search buf for token-delimiter */
        for (i = 0; i < *buflen -1; i++) {
            if (strncmp(&buf[i],delimiter,2)!=0)
                token[i] = buf[i];
            else break;
        }
    

    er scheitert da eventuell mit dem vergleichen, oder mit dem schreiben in token.
    das wird ja nicht abgefangen... da passiert halt irgend ein fehler, aber er läuft die schleife durch oder breaked irgendwann und läuft dann weiter.

    und dann kommt er auch in den folgenden Block, wo alles passt und er '1' zurückgibt.

    Aber was für Probleme könnte er mit dem o.g. Code haben? Was könnte da schief laufen?



  • int getToken(char * token, char * buf, int *buflen, char delimiter[3]) 
    {
        int i;
    
        /* buf is too short to contain token, shortest token is delimiter */
        if (*buflen < 2)
            return (-1);
    
        /* search buf for token-delimiter */
        for (i = 0; i < *buflen - 1; i++) 
        {
            if ( strncmp(&buf[i],delimiter,2) != 0 )
            {
                token[i] = buf[i];
            }
            else
                break;
        }
    
        /* if token not followed by delimiter, return error */
        if ((strncmp(&buf[i], delimiter,2)!=0)) 
        {
            token[0] = '\0';
            return (-1);
        }
        /* null-terminate token and remove the found token from buf */
        else 
        {
            token[i] = buf[i];
            token[i+1] = '\0';
            // ??? memmove(buf, &buf[i+2], BUFSIZE-(i+2));
            *buflen = *buflen - i + 2;
            return (1);
        }
    }
    

    Machst du in memmove alles richtig? &buf[i+2] ist doch jenseits von gut und böse, oder?



  • Nice one 👍

    wenn ich die Zeile auskommentiere, dann funktioniert es alles soweit.

    Allerdings bleibt dann der ursprüngliche String erhalten.
    Es soll aber das heraus"gelöscht" werden, was nach Token geschrieben wird.

    Deshalb wird alles nach vorne verschoben.

    Okay, also es ist so: Ich habe eben diese Funktion schon so fertig gekriegt.
    Ich studier das halt 😉

    Es ist eigentlich SEHR unwahrscheinlich, dass da ein Fehler drin ist.

    Könnte es auch sein, dass ich das irgendwie bei der Übergabe berücksichtigen muss, oder denkst du wirklich, es ist schlichtweg ein Fehler in der Funktion, den man nur beseitigen kann, wenn man in der Funktion selbst etwas manipuliert?

    Trotzdem danke auf jeden Fall 😃 😃 😃



  • Sag mal an, was BUFSIZE ist.
    Kannst du mal gedanklich durchspielen, was passiert, wenn du Hallo übergibst. Wenn dann noch fragen sind, melde dich nochmal.



  • also eigentlich weiss ich nicht , warum dieses memmove() ein problem ist..

    Bevor wir aber aneinander vorbeireden:
    Dass es mit "hallo" nicht funktioniert weiss ich, das sagte ich ja auch.
    aber mit "halloXY" funktioniert es ja auch nicht, solange ich memmove() drinstehen
    habe.

    Ist &buf[i+2] nicht das Null-Terminierungs-Zeichen? Da müsste er doch drauf zugreifen können?!

    BUFSIZE ist nicht explizit festgelegt, also nimmt er den Standard-Wert, der in C schon bereitgestellt ist oder?
    Weiss auch nicht so genau, welcher Wert das ist...



  • Wenn du BUFSIZE in *buflen abänderst...

    char buff[] = "peter12paul12mary";
        char token[256] = "";
        int bufflen = sizeof(buff);
    
        printf ("buff:%s\ntoken:%s\n", buff, token);
        getToken (token, buff, &bufflen, "12");
        printf ("buff:%s\ntoken:%s\n", buff, token);
        getToken (token, buff, &bufflen, "12");
        printf ("buff:%s\ntoken:%s\n", buff, token);
    


  • hi leprechaun.

    hier meine ausgabe, wenn ich es so mache wie du sagtest:

    buff:peter12paul12mary
    token:
    buff:paul12mary
    token:peter
    buff:mary
    token:paul
    Segmentation fault
    

    es funktioniert so auch alles perfekt mit meinem programm, nur
    dass nach allen ausgaben etc. noch ein segmentation fault da ist.
    die funktion macht alles, was sie soll, und es klappt,
    aber dann eben noch dieser segmentation fault.

    hast du eine Ahnung, weshalb ?

    danke



  • hdi schrieb:

    BUFSIZE ist nicht explizit festgelegt, also nimmt er den Standard-Wert, der in C schon bereitgestellt ist oder?
    Weiss auch nicht so genau, welcher Wert das ist...

    Dann sag doch mal, was BUFSIZE ist, sonst sind das Annahmen und keine Fakten. 😕



  • #include <stdio.h>
    #include <stdlib.h>
    
    int getToken(char *token, char *buf, int *buflen, char delimiter[3]) {
        int i;
    
        /* buf is too short to contain token, shortest token is delimiter */
        if (*buflen < 2)
           return (-1);
    
        /* search buf for token-delimiter */
        for (i = 0; i < *buflen -1; i++) 
        {
           if (strncmp(&buf[i],delimiter,2)!=0)
           {  
              token[i] = buf[i];
           } 
           else 
              break;
        }
    
        /* if token not followed by delimiter, return error */
        if ((strncmp(&buf[i], delimiter,2)!=0)) 
        {
            token[0] = '\0';
            return (-1);
        }
    
        /* null-terminate token and remove the found token from buf */
        else 
        {
           token[i] = '\0';
           memmove(buf, (buf + i + 2), strlen(buf) - strlen(token) + 1);
           *buflen = strlen(buf);
           return (1);
        }
    }
    
    int main(void)
    {
       char strbuf[] = "peter12paul12mary";
       char * pctoken;
    
       int ilaenge;
    
       ilaenge = strlen(strbuf);
    
       pctoken = calloc(256,sizeof(char));
    
       printf("\nStart\n");
       printf ("buff:%s\ntoken:%s\nlaenge:%d\n", strbuf, pctoken,ilaenge);   
    
       printf("\nDurchlauf 1");
       getToken (pctoken, strbuf, &ilaenge, "12");
       printf ("\nbuff:%s\ntoken:%s\nlaenge:%d\n", strbuf, pctoken,ilaenge);   
    
       printf("\nDurchlauf 2");
       getToken (pctoken, strbuf, &ilaenge, "12");
       printf ("\nbuff:%s\ntoken:%s\nlaenge:%d\n", strbuf, pctoken,ilaenge);   
    
       free(pctoken);
    
       getchar();
    
       return 0;
    }
    

    :p Zeh Mau :p



  • hey,
    okay also bufsize wird von ner headerdatei eingelesen und hat Wert 1024.

    soll das bedeutet, dass er zuviele bytes schreiben will und deshalb dann auf adressen zugreift, die gar nicht belegt sind?



  • ..und dein beispiel mit calloc() habe ich gerade probiert, ändert aber nichts leider.

    aber ich habe auch nicht die funktion verändert bei memmove(), da sie sicherlich korrekt ist.



  • hdi-logged out schrieb:

    hey,
    okay also bufsize wird von ner headerdatei eingelesen und hat Wert 1024.

    soll das bedeutet, dass er zuviele bytes schreiben will und deshalb dann auf adressen zugreift, die gar nicht belegt sind?

    Aha, wieso so spät mit der Lösung??
    Wenn ich das richtig interpretiere,

    memmove schreibt beginnend ab der Adresse von buf 1024 von (buf + i +2) ab.
    Na wenn das mal nicht in die Hose geht: Segmentation fault!!!

    Zeh Mau



  • hdi schrieb:

    ..und dein beispiel mit calloc() habe ich gerade probiert, ändert aber nichts leider.

    aber ich habe auch nicht die funktion verändert bei memmove(), da sie sicherlich korrekt ist.

    Ich sage zur Funktion: 👎, die ist nicht ganz fehlerfrei!!!



  • Meine Ausgabe:

    Start
    buff:peter12paul12mary
    token:
    laenge:17

    Durchlauf 1
    buff:paul12mary
    token:peter
    laenge:10

    Durchlauf 2
    buff:mary
    token:paul
    laenge:4

    Zeh Mau



  • hey, okay also die funktion will ich nicht ändern, denn das war ja nur ein test von mir. anscheinend ist sie nicht für so kurze strings gedacht, und deshalb funktioniert halt mein beispiel nicht einwandfrei.

    aber ich habe jetzt zumindest dank deiner hilfe verstanden, wie das ganze genau arbeitet.
    vielen dank !!

    bis zum nächten mal 🤡



  • 🤡 Gerne!

    Zeh Mau


Anmelden zum Antworten