Anzeige:
Ergebnis 1 bis 7 von 7

Thema: Array reservieren (malloc)

  1. #1
    Registrierter Benutzer
    Registriert seit
    20.03.2006
    Beiträge
    54

    Array reservieren (malloc)

    Hallo! Ich versuche ein mehrdimensionales Array zu reservieren mit einem Array auf Arrays. Ist das so ok? In meinem großen Programm kommt es zu komischen Fehlern, aber das Testprogramm scheint zu laufen?!

    Code:
    /* arraytest.c */
    
    #include <stdio.h>
    #include <stdlib.h>
    
    #define FALSE 0
    #define TRUE 1
    
    typedef unsigned char   U1;
    typedef signed int      S4;     /* LONGINT */
    
    void **alloc_array_lint (S4 x, S4 y)
    {
        void **array = NULL;
        S4 i, alloc;
        U1 err = FALSE;
    
        array = (void **) malloc (x * sizeof (S4 *));
        if (array != NULL)
        {
            for (i = 0; i < x; i++)
            {
                array[i] = (void *) malloc (y * sizeof (S4));
                if (array[i] == NULL)
                {
                    alloc = i - 1;
                    err = TRUE;
                    break;
                }
            }
            if (err)
            {
                if (alloc >= 0)
                {
                    for (i = 0; i <= alloc; i++)
                    {
                        free (array[i]);
                    }
                }
                free (array);
                array = NULL;
            }
        }
    
        return (array);
    }
    
    void dealloc_array_lint (S4 **array, S4 x)
    {
        S4 i;
    
        for (i = 0; i < x; i++)
        {
            free (array[i]);
        }
        free (array);
    }
    
    int main ()
    {
        S4 **array = NULL;
    
        array = (S4 **) alloc_array_lint (10, 10);
        if (array == NULL)
        {
            printf ("error can't allocate RAM for array!\n");
        }
    
        /* write */
    
        array[0][0] = 10;
        array[0][1] = 5;
    
        /* ... */
    
        dealloc_array_lint (array, 10);
    }
    Valgrind zeigte hier keine Fehler an. Ist das so ok?
    "... der Großteil hier hat einfach keine Lust, jede Pore einer Brotscheibe mit Butter auszuschmieren." - Susu

  2. #2
    Registrierter Benutzer Avatar von sommerfee
    Registriert seit
    02.07.2006
    Beiträge
    1.604
    Zitat Zitat von jay-t Beitrag anzeigen
    Ist das so ok?
    IMHO ja. Mir sind nur drei Kleinigkeiten aufgefallen:

    1. Ich würde bei alloc_array_lint() nicht "void **" sondern "S4 **" als Rückgabetyp nehmen.

    2. Man muß beachten, daß die Werte des Arrays nicht auf 0 initialisiert sind. (Möchte man sie auf 0 initialisiert haben, nimmt man calloc() statt malloc() in der inneren Schleife.)

    3. Bei dem Fehler "array == NULL" wird in main() nicht abgebrochen, nach dem printf() fehlt also ein return(1); oder ähnliches
    Geändert von sommerfee (04-12-2011 um 12:54 Uhr)

  3. #3
    Registrierter Benutzer
    Registriert seit
    14.01.2002
    Beiträge
    657
    würde mir an deiner stelle überlegen mit einem einzelnen malloc zu arbeiten anstatt mit y+1


    int *i = malloc( x*y* sizeof(int) );
    #define ACCESS(i,xi,yi) *(i+xi+yi*x)

  4. #4
    Registrierter Benutzer
    Registriert seit
    23.05.2004
    Beiträge
    592
    Hallo! Ich versuche ein mehrdimensionales Array zu reservieren mit einem Array auf Arrays. Ist das so ok?
    Ich kann soweit auch keinen eindeutigen Fehler entdecken.

    Aber die Präprozessormakros, die Typedefs und die seltsamen gewählten Stellen für Variablendeklarationen sind nicht schön:

    - Streiche TRUE und FALSE und benutze true und false.
    - Deklariere Variablen erst dort wo sie gebraucht werden.
    - Benutze statt S4 entweder signed int wenn du einfach nur ein Integer brauchst, oder size_t wenn es um die Größe von Objekten geht oder z.B. int32_t wenn du wirklich Integer einer bestimmten Größe brauchst.
    - Steiche U1 komplett und benutze einfach unsigned char.

    - Beim Rückgeben des Zeigers aus deiner Anforderungsfunktion den Typ wegzuwerfen kommt mir auch seltsam vor.

    Außerdem kannst du allein durch verwenden deiner Freigabefunktion den Code kürzer und wesentlich übersichtlicher machen. Ungefähr so:
    Code:
    #include <assert.h>
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    void free_array(signed** array, size_t n_rows)
    {
      assert(array || n_rows == 0);
      
      for(size_t c = 0; c != n_rows; ++c)
      {
        free(array[c]);
      }
      free(array);
    }
    
    signed** allocate_array(size_t n_rows, size_t n_columns)
    {
      assert(n_columns > 0);
      
      if(n_rows == 0) { return 0; }
      
      signed** array = static_cast<signed**>(calloc(n_rows, sizeof(signed*)));
      if(!array) {
        errno = ENOMEM;
        return 0;
      }
      
      for(size_t c = 0; c != n_rows; ++c)
      {
        array[c] = static_cast<signed*>(calloc(n_columns, sizeof(signed)));
        if(!array[c]) {
          free_array(array, c);
          errno = ENOMEM;
          return 0;
        }
      }
      
      return array;
    }
    
    int main()
    {
      size_t const n_rows = 111;
      size_t const n_columns = 99;
       
      signed** p = allocate_array(n_rows, n_columns);
      if(!p) {
        fprintf(stderr, "Failed to allocate memory!\nThis program will terminate now.\n");
        return EXIT_FAILURE;
      }
      
      for(size_t c = 0; c != n_rows; ++c)
      {
        p[c][0] = 0;
        p[c][n_columns - 1] = 1;
      }
      
      free_array(p, n_rows);
    }
    Z.b. durch verwenden von new/delete statt malloc/free könnte man es noch ein bißchen kompakter mache, aber bin jetzt erstmal davon ausgegangen dass du wirklich malloc und free benutzen möchtest.


    In meinem großen Programm kommt es zu komischen Fehlern, aber das Testprogramm scheint zu laufen?!
    Wende Valgrind auch auf das große Programm an.

  5. #5
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Zitat Zitat von locus vivendi Beitrag anzeigen
    Zdurch verwenden von new/delete statt malloc/free könnte man es noch ein bißchen kompakter mache, aber bin jetzt erstmal davon ausgegangen dass du wirklich malloc und free benutzen möchtest.
    Du gehst von C++ aus, die Fragestellung klingt aber eher nach plain C.
    Erklärt einige der Dinge, die du bemängelt hast

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  6. #6
    Registrierter Benutzer
    Registriert seit
    23.05.2004
    Beiträge
    592
    Du gehst von C++ aus, die Fragestellung klingt aber eher nach plain C.
    Stimmt...
    Erklärt einige der Dinge, die du bemängelt hast
    ... aber nicht ganz. Alles was ich aufgezählt habe lässt sich sowohl in C als auch in C++ umsetzen. Teilweise hatte C die entsprechende Möglichkeit sogar vor C++, z.B. die Integer Typen mit spezifiziertem Umfang (int32_t und Konsorten). Viele von denen sind zwar genau genommen optional, aber wenn die Standardbibliothek sie nicht hat, werden die Chancen wohl nicht gut stehen sie selber definieren zu können, vorausgesetzt Compiler+Bibliothek sind einigermaßen aktuell.

  7. #7
    Registrierter Benutzer
    Registriert seit
    20.03.2006
    Beiträge
    54
    Danke mal für eure Antworten, werde das jetzt ändern.

    Du gehst von C++ aus, die Fragestellung klingt aber eher nach plain C.
    Ja, stimmt ist einfaches C.
    "... der Großteil hier hat einfach keine Lust, jede Pore einer Brotscheibe mit Butter auszuschmieren." - Susu

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •