Code funktioniert nur manchmal - Anfänger Problem mit Zeigern



  • Hi,
    ich bin relativ neu beim Programmieren in C und wollte mal ein bisschen rumspielen und ein kleines Programm mit Zeigern schreiben. Das Programm funktioniert normal schon, allerdings bekomme ich bei jedem 3ten mal ausführen die sortierte Liste falsch zurück, d.h. es wird eine Zahl nicht korrekt ausgegeben. z.B. sollte dort eine 12 oder 5 stehen und es wird -2878367874 oder soetwas angezeigt. Ich vermute es liegt an irgendwas mit den Zeigern, dass die also irgendwo falsch hinzeigen, ich finde aber nicht den Fehler. Hier der Code:

    #include <stdio.h>
    #include <stdlib.h>
    
    int n;
    int *Integer_ptr;
    
    int getN()
    {
        int i;
        printf("Wieviele Zahlen wollen sie eingeben ?\n");
        printf("Hier eingeben: ");
        scanf("%d", &i);
        return i;
    }
    
    void getNumbers(int a)
    {
        int j = 0;
        while (j < a) {
            printf("\nGeben sie die %d. Zahl ein: ", j+1);
            scanf("%d", Integer_ptr);
            j++;
            Integer_ptr++;
        }
        Integer_ptr = Integer_ptr - a;
    }
    
    void printList(int a)
    {
        int k;
        printf("\nDie Liste der Zahlen lautet: [ ");
        for(k = 0; k < a; k++) {
            printf("%d ", *Integer_ptr);
            Integer_ptr++;
        }
        printf("]");
        Integer_ptr = Integer_ptr - a;
    }
    
    void sortIt(int a)
    {
        int getauscht = 0;
        int count = 0;
        int temp;
        while(count < a) {
            if (*Integer_ptr <= *(Integer_ptr + 1)) {
                count++;
                Integer_ptr++;
            } else if (*Integer_ptr > *(Integer_ptr + 1)) {
                        temp = *Integer_ptr;
                        *Integer_ptr = *(Integer_ptr + 1);
                        *(Integer_ptr + 1) = temp;
                        getauscht++;
                        count++;
                        Integer_ptr++;
                    }
        }
        Integer_ptr = Integer_ptr - a;
        if (getauscht != 0) {
            sortIt(a);
        } else {
            printf("\nDie Liste wurde sortiert!");
        }
    }
    
    int main()
    {
        n = getN();
    
        printf("\nn = %d", n);
    
        Integer_ptr = (int) malloc(n*sizeof(int));
    
        getNumbers(n);
    
        printList(n);
    
        sortIt(n);
    
        printList(n);
    
        getch();
    
        return 0;
    }
    


  • 1. soltest du den Integer_ptr in den Funktionen nicht verändern. Arbeite mit einer Kopie.
    2. noch besser, du verzichtest auf globale Variablen. Du kannst n und Integer_ptr an die Funktionen übergeben.
    Zumal eine global Variable mit Namen n zu verdammz foesen Fehlern führen kann.

    Dein Problem liegt aber an dem Schleifenende in sortIt.
    Wenn count = a-1 ist, greifst du bei *(Integer_ptr + 1) auf auf ein Element zu, das nicht existiert.

    Da du das Schleifenende kennst, ist da auch eine for-Schleife hübscher.



  • - globale Variablen sind Müll

    • (int) malloc ist falsch und auch das korrekte (int*) malloc ist aus C-Sicht Müll
      - getch ist kein Standard
      - statt *Integer_ptr und Integer_ptr++ schreibt man besser Integer_ptr[count]
      - deine Sortierfunktion ist prinzipiell richtig, wenn auch falsch implementiert wie schon erwähnt, auch bietet die C-Standardbibliothek mit qsort hierfür eine (bei korrekter Verwendung fehlerfreie) Alternative an


  • Wutz schrieb:

    ..., auch bietet die C-Standardbibliothek mit qsort hierfür eine (bei korrekter Verwendung fehlerfreie) Alternative an

    Wie soll man den die Grundlagen von C lernen, wenn man immer gleich die Funktionen der Standardbibliothek nimmt.



  • So, danke erstmal an alle, die so nett geholfen haben !!
    Ich weiß, dass der Code nicht sonderlich schön ist, ich hab das nur kurz zusammengeschustert um was auszuprobieren. Danke trotzdem für die Hinweise !!
    Ich hab noch ein paar Fragen dazu:
    - Warum sollte n als Variable nicht benutzt werden? Ist n noch für was anderes als einen Zeilenumbruch reserviert ?
    - Was wäre eine Alternative zu (*int) malloc ? Ich dachte das wird so gemacht, weil malloc doch nur einen nicht näher definierten Zeiger zurückgibt und ich ihn doch auf einen int-zeiger caste!?!?

    Danke nochmal 🙂

    Grüße,
    wm

    PS: Ja qsort wollte ich nicht benutzen, hab mir irgendeinen Sortieralgorithmus zusammengedichtet, nur damits einigermaßen funktioniert! wie gesagt, das ist nur eine Übung und hat keinen weiteren Sinn 🙂



  • Ich bezog mich auf n als globale Variable.
    Als lokale Variable kannst du es für Schleifenvariablen und Indizes benutzen.
    Nur wenn du dann einmal vergisst die Variable lokal zu definieren, hast du einen sehr sehr üblen Fehler.

    Variablennamen sollten aussagekräftige Namen haben.

    Globale Variablen immer vermeiden.

    n als Variablennamen und das \n als Escapesequenz haben nichts miteinander zu tun.

    Du brauchst das Ergebnis von malloc nicht casten.
    (Das gilt nicht für C++, aber wir sind hier im C Unterforum)



  • wildermann schrieb:

    - Warum sollte n als Variable nicht benutzt werden? Ist n noch für was anderes als einen Zeilenumbruch reserviert ?

    Ein Bezeichner n hat mit '\n' genau garnichts zu tun. Es besteht zum Bleistift die Gefahr, daß du n irgendwann als Schleifenvariable nimmst und damit das Globale n verdeckst. Wenn im schlimmsten Fall schon globale Variablen, dann wenigstens mit aussagekräftigen Namen.

    wildermann schrieb:

    - Was wäre eine Alternative zu (*int) malloc ?

    new ?

    wildermann schrieb:

    Ich dachte das wird so gemacht, weil malloc doch nur einen nicht näher definierten Zeiger zurückgibt und ich ihn doch auf einen int-zeiger caste!?!?

    Das wird in C++ (leider) so gemacht, weil ein cast von void* nach sonstwas* in C++ nicht implizit erfolgt, wie in C.

    // edit:

    DirkB schrieb:

    (Das gilt nicht für C++, aber wir sind hier im C Unterforum)

    Glatt ignoriert 😉



  • Swordfish schrieb:

    new ?

    Wie der Name schon andeutet: Neumodischer Krams.

    🤡



  • wildermann schrieb:

    - Was wäre eine Alternative zu (*int) malloc ?

    malloc/calloc ⚠ OHNE DEN CAST!!!! ⚠


Log in to reply