dynamisches int-feld??



  • wer kann mir helfen dieses feld wirklich dynamisch zu gestalten! es sollte so funktionieren, dass der benutzer F6 (EOF) eingibt, und der compiler (oder wer auch immer) dann checkt, wenn keine Daten mehr eingegeben werden sollen! danke für die hilfe!!

    #include <stdio.h>
    #include <malloc.h>

    main() {

    int i, anz, *feld;
    printf("Wieviele Zahlen wollen Sie eingeben: \n");

    scanf("%d",&anz);
    feld = (int*)malloc(anz*sizeof(int)); //Zeigervar feld, wird "anz"

    if(feld==NULL ) { //Fehlerabfrage
    printf("Es ist kein Speicher frei!\n\n");
    return -1;
    }

    for(i=0; i<anz; i++) {

    printf("Bitte geben sie die %d.Zahl ein: ", i+1);
    scanf("%d", &feld[i]);
    }
    printf("Das Feld lautet: ");
    for(i=0; i<anz; i++)
    printf("%d ", feld[i]);
    }



  • Wenn ich Dich richtig verstehe, willst Di das Array dynamisch erweitern. Also ohne vorherige Festlegung, wie viele Elemente tatsächlich eingelesen werden sollen...

    Ich hab' hier mal eine kleine Lösung ausgearbeitet:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
        int i, groesse=1, anz=0, *feld = NULL;
    
        while (printf("Bitte Zahl eingeben: "), scanf("%d", &i) == 1)
        {
            if (++anz >= groesse && (feld = realloc(feld, (groesse*=2)*sizeof(int))) == NULL) 
            {
                puts("Out of memory");
                exit(0);
            }
            feld[anz-1] = i;
        }
    
        anz && printf("Das Feld lautet: ");
        for(i=0; i<anz; i++)
            printf("%d ", feld[i]);
    
        return 0;
    }
    

    [ Dieser Beitrag wurde am 08.01.2003 um 18:10 Uhr von mady editiert. ]



  • @mady:

    genau, das war mein problem!

    vielen, vielen dank!



  • Das kannst du ganz einfach realisieren

    (Code ungetestet)

    #include <stdlib.h>
    #include <signal.h>
    #include <stdbool.h>
    #define BLOCKSIZE 10
    
    bool stop=false;
    
    void stop_loop(int)
    {
      stop=true;
    }
    
    int main()
    {
      size_t sz=BLOCKSIZE;
      int *array=malloc(sizeof(int)*10);
      int i=0;
      if(signal(SIGTERM,stop_loop)==SIG_ERR)
        return 1;
      for(;!stop;++i)
      {
        if(i>sz)
        {
          sz+=BLOCKSIZE;
          if(realloc(array,sz*sizeof(int))==NULL)
          {
            free(array);
            return 1;
          }
        }
        scanf("%d",&array[i])
      }
      if(realloc(array,i*sizeof(int))==NULL)
      {
        free(array);
        return 1;
      }
      //...
      free(array);
      return 0;
    }
    

    Ich hoffe, dass der Code dir einen Hinweis gibt, wie man das realisieren kann.

    BTW.
    -Caste niemals den Rückgabewert von malloc!
    -Und C99 erwartet, dass main so deklariert wird, wie hier beschrieben.
    -und malloc.h ist mir unbekannt der Header, malloc ist eigentlich in stdlib.h definiert

    [edit]uff, war ich langsam 😉 naja meine Version sollte aber schneller sein als madys![/edit]

    [ Dieser Beitrag wurde am 08.01.2003 um 18:18 Uhr von kingruedi editiert. ]



  • Original erstellt von kingruedi:
    **Das kannst du ganz einfach realisieren

    (Code ungetestet)

    /* ... snip .... */
      if(realloc(array,i*sizeof(int))==NULL)
      {
        free(array);
        return 1;
      }
    /* ... snip .... */
    }
    

    ....

    [edit]uff, war ich langsam 😉 naja meine Version sollte aber schneller sein als madys![/edit]**

    Naja .... Ob Deine Version schneller ist, hängt dann wohl von der Menge der Eingabedaten ab. Egal - mit signal() die Sache zu machen ist clever, aber funktioniert das auch mit EOF-Flags bei Eingabedaten??

    realloc() sollte man in dieser Form nicht verwenden (Ich habe das -ungetestet- gelesen... :)).



  • für EOF

    if(scanf("%d",&array[i])==EOF)
      break;
    

    😉

    realloc:
    In der Manpage von realloc steht:

    If realloc() fails the original
    block is left untouched - it is not freed or moved.

    also muss man den Speicher explizit freigeben!

    BTW.
    sollte meine Version immer schneller sein, sobald ein Aufruf von malloc/realloc gespart wird und die Anzahl der gelesenen Zahlen > 1 ist, ansonsten gleichschnell (obwohl realloc(NULL noch langsamer sein könnte als malloc, wenn das erste Argument auf NULL geprüft wird, aber das vernachlässigen wir mal)

    Also
    Zahlen:
    1 deine Version sollte schneller sein
    2 ca. gleichschnell
    3>= meine schneller

    :p

    [ Dieser Beitrag wurde am 08.01.2003 um 19:59 Uhr von kingruedi editiert. ]



  • EOF: OK!
    realloc: Sicherlich musst Du den Speicher weiterhin freigeben. Das ist nicht der Grund meines Postings. Aber: realloc() liefert einen Zeiger auf den neuen Speicherbereich zurück, wenn der Platz im alten nicht ausreichen sollte; NULL, wenn kein neuer Speicher besorgt werden konnte. 'array' ist in Deinem Beispiel also nicht unbedingt weiterhin gültig, nach dem realloc()-Aufruf. Ein Beispiel:

    void *p = NULL;
    /* ... bla ... */
    {
        void *t = realloc(p, new_size);
        if (t == NULL) {
            /* Error & Abbruch */
        }
        p = t;
    }
    /* ... blub ... */
    

    [ Dieser Beitrag wurde am 08.01.2003 um 20:42 Uhr von mady editiert. ]



  • Original erstellt von kingruedi:
    **...
    Also
    Zahlen:
    1 deine Version sollte schneller sein
    2 ca. gleichschnell
    3>= meine schneller

    :p

    [ Dieser Beitrag wurde am 08.01.2003 um 19:59 Uhr von [qb]kingruedi** editiert. ][/QB]

    Hmmm .... naja ....

    Wenn ich das richtig sehe, allozierst Du Speicher alle BLOCKSIZE-Schritte. Dass bedeutet, dass Du bei n zahlen n/BLOCKSIZE mal realloc() aufrufst. Oder hab' ich da was übersehen?

    Meine Version besorgt zuerst Speicher für 1 Element, dann für 2, 4, 8, 16, usw. umso mehr Elemente vorliegen, desto weniger oft ruft meine Version realloc() auf....



  • Original erstellt von kingruedi:
    **
    1.)
    //....
    if(signal(SIGTERM,stop_loop)==SIG_ERR)
    //....
    [/cpp]
    2.)
    -Caste niemals den Rückgabewert von malloc!
    **

    zu 1.)
    a) woher kommt das signal SIGTERM ?
    b) laut man signal soll der zweite Parameter ein (int) als param übergeben?
    (fehlt) und welcher wert wäre das?

    zu 2.)
    Warum nicht malloc casten?

    typedef struct s_vorlesungen{
            // Zeiger auf den Speicherplatz einer strucut s_vorlesungen
            struct s_vorlesungen *next;
            struct s_vorlesungen *prev;
            char *data [MAX_DATA] ;
    }vorlesung; 
    
    // Startpunkt für das Verzeichnis ist zu Beginn leer
    struct s_vorlesungen *erster, *letzter , *aktueller ; 
    //...
        erster = letzter = aktueller = (struct s_vorlesungen *) malloc ( sizeof(vorlesung ) );
    

    OHNE casting maulte gcc unter Linux ! Obwohl es sich bei linker und rechter Seite jedesmal um pointer handelt ??!!

    Gruß Hanns



  • P.s.
    Streich mal die Frage zu 1.)
    da hatte ich wohl nicht richtig gelesen
    Hanns 😃



  • Original erstellt von ^Hanns:
    **....
    OHNE casting maulte gcc unter Linux ! Obwohl es sich bei linker und rechter Seite jedesmal um pointer handelt ??!!

    Gruß Hanns**

    http://www.c-plusplus.net/ubb/cgi-bin/ultimatebb.cgi?ubb=get_topic&f=10&t=002694


Anmelden zum Antworten