Segmentationfault in for()



  • hallo,

    ich habe diese for-schleife und noch in der ausfuehrung der ersten schleifenbedingung gibt es einen segmentation fault.

    char *p_bffr, *pc, *pc2;
    unsigned int j;
    j = 0;
    
    for ( ((pc = strchr(p_bffr, '\n')) && (pc2 = p_bffr)); (pc = strchr(pc2, '\n')) != NULL; ) {
    	if (pc == NULL)        //da bei erster schleifenausfuehrung nich die schleifenbedingung
                break;                   //geprueft wird
    
    	FILE_INDEX[j] = (char *) malloc((pc-pc2)*sizeof(char));
    	strncpy(FILE_INDEX[j], pc2, (pc-pc2));
    	FILE_INDEX[j][pc-pc2] = '\0';
    	pc2 = pc+1;
    	j++;
    }
    

    p_bffr zeigt auf einen puffer, der zeichenketten die mit '\n' voneinander getrennt sind enthaelt. diese schleife soll die strings in p_bffr's puffer trennen und jeweils einem element im array von *chars FILE_INDEX zuweisen. aber schon die schleifeninitialisierung ruft einen segmentation fault auf und ich kann den leider nicht finden und hoffe, dass ihr mir sagen koennt, wo der fehler liegt.

    Gruss caspar



  • Wenn ich mich nicht irre reservierst du um 1 Byte zu wenig Speicher, nämlich genau um das 0 Zeichen.



  • jou, die schleife for hat folgenden aufbau.

    for ( BLA; BLUBB; BLOPP)
    {
    EGAL
    }
    

    du hast alles richtig, nur hast du BLA vergessen, hier findet eine sog. initialisierung statt, zum beispiel das setzen einer zählvariablen auf null. das darf man nicht einfach weglassen --- das ist der fehler bei deinem code ---, sondern man muß trotzdem ; in die klammer schreiben, also

    for ( ; BLUBB; BLOPP)
    

    und wenn du zwei bedingungen zum überprüfen hast (das ist BLUBB), dann trennst du die mit einem einfachen komma.

    alles klärchen? 🕶



  • @scrub:

    Die Syntax ist vollkommen korrekt, wenn auch ziemlich 'abgefuckt' - ich bin übrigens auch darauf reingefallen 🙂 aber ein zweiter Blick hat den fiesen && Trick enthüllt...



  • hä? ich seh da keine richtige initalisierung.... du meinst doch nicht etwa, dieses (miep = x) && (mööp = y) wäre eine richtige initaislierung?!? wow, ich dachte nicht, daß es so gehen würde *wundertsich* ich dachte, es geht nur miep = x, mööp = y;

    very strange 🤡



  • a && b ist die 'kurzform' für

    if(a) b;

    was in diesem fall natürlich korrekt ist:

    initialisiere pc2 nur, wenn pc auf ein \n zeigt. Mit , wäre es aber IMHO klarer. Ich würde das ganze for sowieso etwas anders schreiben...



  • sorry für meinen anstehenden Flame, aber das ist wirklich mieser Code. Ich musste mir die for-Schleife mehrmals anschauen, um überhaupt ihren Aufbau zu verstehen. Formatiere deinen Code anständig und du wirst solche Fehler leichter finden.



  • der code entspricht sicherlich nicht richtlinien um leserlich zu wirken... ich bin (was euch sicherlich aufgefallen ist ;)) kein profi, muss nicht im team arbeiten und ich wollte einfach eine bedingung in die schleife bauen und in bsd-sourcen findet man oefter die verwendung des &&-operators in so einer weise. ich habe auch mit dem gedanken gespielt anstatt && den ?:-operatoren zu verwenden - aber das ist es eben, einen operanden des ?:-operators haette ich nicht genutzt, was sicher auch nicht fuer kompetenz spricht. aber das soll doch nicht gegenstand des threads werden ?!

    @Shade Of Mine
    1.ja ein feld zu wening haette ich initialisiert, wenn ich die 0 rangehangen haette, aber ich ersetzen ja das '\n' durch eine 0, daher sollte es stimmen,... wobei ich mich immer noch verrechnet haben koennte.
    2.ja ich koennte auch ein komma verwenden, im schleifenkoerper habe ich ja schliesslich if (pc == NULL) break; (ja diese doppelte pruefung ist eigentlich viel schlimmer als die unleserliche schrift).

    Gruss caspar

    [habe aus komme komma berichtigt]



  • Caspar schrieb:

    der code entspricht sicherlich nicht richtlinien um leserlich zu wirken...

    Nimm solche Sachen nicht allzu ernst - arbeite einfach konsequnet an deinem Stil, dann wird er schon besser.

    ich wollte einfach eine bedingung in die schleife bauen und in bsd-sourcen findet man oefter die verwendung des &&-operators in so einer weise.

    autsch - das spricht nicht gerade für BSD

    ich habe auch mit dem gedanken gespielt anstatt && den ?:-operatoren zu verwenden - aber das ist es eben, einen operanden des ?:-operators haette ich nicht genutzt, was sicher auch nicht fuer kompetenz spricht. aber das soll doch nicht gegenstand des threads werden ?!

    Wie würdest du dort ?: verwenden? Das ist mir nicht klar

    btw: ich würde kein for nehmen - dann ist die Sache gelaufen 🙂

    1.ja ein feld zu wening haette ich initialisiert, wenn ich die 0 rangehangen haette, aber ich ersetzen ja das '\n' durch eine 0, daher sollte es stimmen,... wobei ich mich immer noch verrechnet haben koennte.

    OK, rechnen wir mal.
    Nehmen wir "\n" als string
    pc zeigt auf '\n' und pc2 auch
    folglich ist pc-pc2 0
    wir machen also ein malloc(0) was IIRC nicht verboten ist.
    Aber Achtung:
    FILE_INDEX[j][0]='\0';
    das ist n 'Autsch'
    Denn FILE_INDEX[j] hat ja exakt 0 Byte speicher...



  • also, zwei sachen: der segmentation fault wurde nicht vom aufgefuehrten codeblock verursacht, der fehler lag in der komponente des programms, die das buffer, auf das p_bffr zeigt, fuellt 🙄 . egal, so sehe ich zumindest, dass eine fehlerbehandlung fuer solch einen fall fehlt.

    den :? haette ich etwa so eingebaut:

    for ( (pc = strchr(p_bffr, '\n')) ? (pc2 = p_bffr) : NULL; (pc = strchr(pc2, '\n')) != NULL; ) {
    ...// wie erwaehnt: noch haesslicher mit dem NULL
    }
    

    um ehrlich zu sein, habe ich mit dem gedanken gepielt '...'? '...' : break zu setzen, bis ich mir vergegenwaertigte, dass das nicht moeglich ist.

    und das mit dem string, der nur aus '\n' besteht, das habe ich schlicht und einfach garnicht bedacht - mist. da kann ichs wirklich mit der for-schleife sein lassen, wenn ich auch noch auf so eine bedingung pruefen muss. naja, schoen, dass es dir aufgefallen ist.

    so far...
    Caspar



  • Caspar schrieb:

    und das mit dem string, der nur aus '\n' besteht, das habe ich schlicht und einfach garnicht bedacht - mist. da kann ichs wirklich mit der for-schleife sein lassen, wenn ich auch noch auf so eine bedingung pruefen muss. naja, schoen, dass es dir aufgefallen ist.

    Das Problem tritt auch bei "bla\n\nbla" auf. bzw. hast du das problem eigentlich immer:

    p="bla\n"
    pc zeigt auf p+3 und pc2 zeigt auf p
    differenz ist 3 - du reservierst 3 bytes und sagst dann buffer[3]='\0' und schon wieder gibts nen seg fault 🙂

    einfach n +1 einfügen und die Sache ist gegessen.

    btw:

    start=buffer;
    while(i=strchr(start, '\n'))
    {
      //malloc und der ganze mist
    
      start=i+1;
    }
    

    so ists doch irgendwie klarer, oder?



  • ich glaube, die schleife uebernehme ich :D. danke.

    Caspar


Anmelden zum Antworten