Zufällig laufendes Programm



  • Hallo,

    es wäre super wenn jemand mal einen kurzen Blick auf das folgende Listing werfen könnte. Das Programm kompiliert, läuft manchmal korrekt und manchmal bekomme ich einen Speicherallozierungsfehler. Ich habe mich wohl mit den Pointern vertan.

    #include<stdlib.h>
    #include<stdio.h>
    #define MAX_ZAHL 100
    
    void fill(int *, int *, int *);
      int i;
      int j;
    
    int main()
    {
        int *memptr;
        int *offset;
    
        int base[5] = {10, 25, 31, 50, 70};
        int top[5] = {20, 30, 32, 60, 100};
        memptr = (int *) malloc(MAX_ZAHL * sizeof(int));
        offset = memptr;
        if(memptr == NULL)
        {
            printf("\nNicht genuegend Speicher!!!");
            exit(1);
        }
        for(i=0; i < MAX_ZAHL; i++)
        {
            *offset++ = 0;
        }
        offset = memptr;
    	fill(base, top, offset);
    	offset = memptr;
        for(i = 0; i < MAX_ZAHL; i++)
        {
            printf("\t%.0i ", offset[i]);
        }
        free(memptr);
        printf("\nSpeicherplatz wieder freigegeben!");
        return 0;
    }
    
    void fill(int *base, int *top, int *offset){
     for(i = 0; i < MAX_ZAHL; i++)
        {
            offset = offset + 1;
            for(j = 0; j < 5; j++)
            {
                if(i >= base[j] && i <= top[j])
                {
                    *offset = j + 1;
                }
            }
        }
    
    }
    

    Falls es von belang ist: ich verwende Windows 7 64bit System.

    lg,
    Markus

    PS: wenn ich es außerhalb von mingw starten will erhalte ich die Fehlermeldung:

    "libgcc_s_dw2-1.dll ist nicht installiert bitte installier das erneut"



  • offset = offset + 1;

    muss am Ende des Schleifendurchlaufs stehen. Du setzt ja nie offset+0 sondern faengst mit offset+1 an...

    i und j sollten uebrigens lokale Variablen sein und keine Globalen.

    Fuer solche Situationen gibts uebrigens Debugger 😉



  • ah ok danke für die antwort. Ich hab gedacht das gehört so weil ich schreibe ja auch:

    for(i=0; i < MAX_ZAHL; i++)
        {
            *offset++ = 0;
        }
    

    und ich dachte dass da zuerst die Adresse offset um vier byte erhöht wird und dann der Pointer gebildet wird, deshalb habe ich das so geschreiben. Wäre zwar ne ziemliche Speicherverschwendung von den Jungs von gcc aber es gibt schon gründe ein byte aufzugeben (periodische boundaries bei stacks z.B.).

    Danke für den hinweis aber ich hab die ganz bewusst lokal gemacht um speicherplatz zu sparen. Es wäre bei diesem Programm sinnlos zweimal lokale variablen zu allozieren. Andererseits ist es natürlich sinnlos bei diesem Programm auf 8 Byte Speicherplatz zu achten :D; also bitte keinen Glaubenskrieg ;-).

    Danke und liebe Grüsse,

    Markus



  • sphererunner schrieb:

    ah ok danke für die antwort. Ich hab gedacht das gehört so weil ich schreibe ja auch:

    for(i=0; i < MAX_ZAHL; i++)
        {
            *offset++ = 0;
        }
    

    und ich dachte dass da zuerst die Adresse offset um vier byte erhöht wird und dann der Pointer gebildet wird, deshalb habe ich das so geschreiben. Wäre zwar ne ziemliche Speicherverschwendung von den Jungs von gcc aber es gibt schon gründe ein byte aufzugeben (periodische boundaries bei stacks z.B.).

    Achtung.
    Du musst das ganze zuende denken.
    in deinem Beispiel machst du ja in der Schleife nichts anderes mit offset als 0 zuzuweisen. Und *offset++ = 0; ist nur die kurzschreibweise fuer
    *offset=0;
    offset=offset+1;

    und jetzt sollte auch klar sein warum die Schleife in fill() falsch ist. Dort schreibst du naemlich
    offset=offset+1;
    *offset=X;

    dh zuerst erhoest du offset und weist dann erst zu. Das bedeutet dass du einfach immer um eins daneben bist.

    Danke für den hinweis aber ich hab die ganz bewusst lokal gemacht um speicherplatz zu sparen. Es wäre bei diesem Programm sinnlos zweimal lokale variablen zu allozieren. Andererseits ist es natürlich sinnlos bei diesem Programm auf 8 Byte Speicherplatz zu achten :D; also bitte keinen Glaubenskrieg ;-).

    Das ist der falsche Gedankengang. Vermeide immer und ueberall globale Variablen mit aller Kraft. Denn es ist viel wichtiger dass dein Code korrekt laeuft als alles andere.

    Es ist viel zu leicht ploetzlich Schleifen zu verschachteln (zB weil du fill in einer Schleife aufrufst und ploetzlich benutzen beide Schleifen i als Variable). Das ist keine Glaubensfrage.



  • Das ist der falsche Gedankengang. Vermeide immer und ueberall globale Variablen mit aller Kraft. Denn es ist viel wichtiger dass dein Code korrekt laeuft als alles andere.

    Es ist viel zu leicht ploetzlich Schleifen zu verschachteln (zB weil du fill in einer Schleife aufrufst und ploetzlich benutzen beide Schleifen i als Variable). Das ist keine Glaubensfrage.

    Mensch du hast recht. Die 8 Byte sind durchaus gut investiert.

    lg,
    Markus

    PS: Nochmals danke für den schnellen Support.



  • Du musst die unbendingt nochmal den Unterschied zwischen Post- und Pre-increment durchlesen.
    Es ist nicht nur eine Geschmacksfrage auf welcher Seite von der Variablen das ++ (bzw. --) steht.
    *offset++ = 0; macht etwas anderes als *++offset = 0;


Anmelden zum Antworten