Zeiger - In die Irre geführt? - Dynamische Speicherverwaltung



  • Hallo,

    ich schreibe ein Programm für 2 Warengruppen (2 Speicherfelder). Deren Menge gebe ich an. Anschließend werden sie im Speicherfeld 3 verbunden. Es dient als Lernhilfe zur dynamischen Speicherverwaltung.

    Ablauf:
    _________________
    Wieviele Waren hat Gruppe 1: -> Eingabe einer Zahl = Anzahl der Waren 1 <-

    Wieviele Waren hat Gruppe 1: -> Eingabe einer Zahl = Anzahl der Waren 2 <-

    (Programm) Waren zusammen:

    -> Es erscheint eine Liste mit den Warenmengen (unterscheidbar anhand der Zahlen- https://dl.dropboxusercontent.com/u/29730688/waren.PNG) <-
    _________________

    Problem: Innerhalb der Unterfunktion wird die Liste richtig ausgegebn. Innerhalb des Hauptprogramms sind nur wirre Zahlen drinnen. Obwohl es derselbe Zeiger ist.

    Programme: Main.c

    #include "stock.h"
    
    int main() {
        long *ware, *ware1, *ware2;
        long w_size, w_size1, w_size2;
        printf("********* WARE - Dynamischer Speicher **********\n\n");
    
    //Ware 1
        printf("\nWieviele Waren hat Gruppe 1: ");
        scanf("%ld", &w_size);
        ware=alloc_ware(w_size); //Erstellung des Feldes 1 mit Größe x_size1
        long j;
        for (j=0; j < w_size ; j++) {
            ware[j]=rand()%30+1;    //Dient zur unterscheidung der Waren innerhalb der Gruppen
        }
        print(ware,w_size); //Listenansicht
    
    //Ware 2
        printf("\nWieviele Waren hat Gruppe 2: ");
        scanf("%ld", &w_size1);
        ware1=alloc_ware(w_size1); //Erstellung des Feldes 2 mit Größe w_size2
        for (j=0; j < w_size1 ; j++) {
            ware1[j]=rand()%30+1;
        }
        print(ware1,w_size1); //Listenansicht
    
    //Ware verbunden
        printf("\n____Waren zusammengefuegt____\n");
        w_size2 = w_size1+w_size;                                       //Menge zusammen
        append(ware,w_size,ware1,w_size1,ware2,w_size2);                     //Ware zusammenfügen
        print(ware2,w_size2);                                                     //Funktioniert nicht! Sollte es aber!
    
        free_ware(ware);
        free_ware(ware1);
        free_ware(ware2);
        return 0;
    }
    

    Stock.c

    #include "stock.h"
    
    //Erstellen eines dynamischen Feldes
    long *alloc_ware(long w_size) {
        long *wadress=0;
        if ((wadress = malloc(w_size*sizeof(long)))) {
            printf("-> Speicher reserviert, %ld Waren erstellt\n", w_size);
            return wadress;
        }
        else {
            fprintf(stderr, "-> Kein Speicher frei!");
            return 0;
        }
    }
    
    //Speicher frei machen
    void free_ware (long *w_mem) {
        if (w_mem) {
            free(w_mem);
        }
        w_mem=0;
    }
    
    //Listenansicht
    void print(long *w_mem, long w_size) {
        long i;
        for (i=w_size-1 ; i>=0 ; i--) {
            printf ("Ware Nr. %ld: %ld\n", i+1, w_mem[i]);
        }
    }
    
    //Mach aus 2 Warengruppen 1e lange
    long connect(long *w_mem1, long size1,
                 long *w_mem2, long size2,
                 long *w_mem3, long size3) {
        long j,f;
        long *w_mem_temp;                                         //temporäres Feld
        if (( w_mem_temp = malloc(size3*sizeof(long)) )) {
            for (j=0 ; j<size1 ; j++) {                           //Fülle ersten Teil des Feldes
                w_mem_temp [j] = w_mem1[j];
            }
    
            for (f=0 ; f< (size2) ; f++) {                       //Fülle zweiten Teil des Feldes
                w_mem_temp [f+size1] = w_mem2[f];
            }
            w_mem3=w_mem_temp; 
    
    //      print(w_mem3,size_3);     -> Würde funktionieren! Soll es allerdings auch im Hauptprogramm!!!!
    
            return 1;
        } else {
            fprintf(stderr, "\nKonnte Speicher nicht bereitstellen!\n");
            exit (-1);
        }
        return 1;
    }
    

    Stock.h

    #ifndef STOCK_H_INCLUDED
    #define STOCK_H_INCLUDED
    #endif // STOCK_H_INCLUDED
    
    #include <stdio.h>
    #include <stdlib.h>
    
    long *alloc_ware(long w_size);
    void free_ware (long *w_mem);
    void print(long *w_mem,long w_size);
    long connect(long *w_mem1, long size1,
                long *w_mem2, long size2,
                long *w_mem3, long size3);
    

    Danke schonmal im Voraus fürs durchlesen 🙂 Hoffe jemand kommt drauf


  • Mod

    Ein paar Bemerkungen:

    #ifndef STOCK_H_INCLUDED
    #define STOCK_H_INCLUDED
    #endif // STOCK_H_INCLUDED

    
    Das ist nicht ganz der Sinn von Includeguards :p  
    
    Das löst zwar in diesem Fall nicht deinen Fehler aus, das endif gehört aber trotzdem ganz ans Ende.
    *  connect und append sollen die gleiche Funktion sein, oder? append heißt übrigens etwas an etwas anderes hinten anhängen; connect heißt etwas mit etwas anderem verbinden; concatenate heißt eines oder mehrere Dinge hintereinander hängen.
    *  Wenn du eine Variable in einer Funktion ändern möchtest und diese Änderung nach draußen getragen werden soll, dann musst du einen Zeiger auf diese Variable an die Funktion übergeben. Wenn die Variable ein Zeiger ist, dann musst du logischerweise einen Zeiger auf diesen Zeiger übergeben.  
    
    Das heißt, derzeit änderst du deine lokale Kopie, w_mem3, von ware2. ware2 selbst wird aber nicht verändert. Daher das von dir beobachtete Verhalten.
    *  Nach diesem Fehler habe ich übrigens gar nicht aktiv gesucht, ich habe den Code einfach compiliert und mein Compiler hat mir direkt gesagt, dass ware2 nicht initialisiert wird und das w_mem3 nicht benutzt wird. Das könnte dein Compiler sicher auch. Versuch mal heraus zu bekommen, wie man Compilerwarnungen aktiviert. Warnungen solltest du behandeln wie Fehler.
    
    Weiter habe ich mir den Code nicht angesehen; wenn ich über den Rest des Codes nichts sage, heißt das also nicht, dass dieser fehlerfrei sein muss, ich habe ihn nur nicht genau angeguckt.


  • - Das ist richtig, es sollte connect heißen, nicht append, danke für die Rückmeldung 🙂

    - "ware2" ist in der Form ja ein Zeiger. Und ich übergebe dessen Inhalt als Adresse an den Parameterzeiger in der connect-Unterfunktion. Damit sollte "ware3" auch auf die Adresse zeigen, auf die "ware2" gezeigt hat, oder?

    - Stimmt, den Compiler habe ich vergessen anzugeben, meine gibt dasselbe wie deiner aus, allerdings nur für "ware2":

    C:\User\main.c|32|warning: 'ware2' is used uninitialized in this function [-Wuninitialized]|
    


  • Zeile 47 zeigt, dass du call-by-value nicht verstanden hast (und dass du dich höchstwahrscheinlich durch die dümmliche (aber leider weit verbreitete) Meinung, Zeiger als Funktionsparameter wären call-by-reference, hast irritieren lassen)


Log in to reply