Malloc Funktion mit mehrdimensionalen Arrays!



  • Moin moin,

    mir stellt sich mal wieder ein Problem.
    In einem Programm das ich schreibe werden unheimlich viele Strings eingelesen und zwischengespeichert werden. Dafür möchte ich gerne die Malloc Funktion nutzen, soweit so gut.

    Bei den Daten handelt es sich um 44 Größen die mit jeweils 1000 Werten in je 50 Zeichen zur Verfügung stehen. Das würde bedeuten 2200000 Bytes (char).

    Wenn ich mit Malloc einen Speicher in der Größe reserviere:

    char *datenfeld = (char*) malloc(2200000 * sizeof(char));

    if (datenfeld==NULL)
    {
    goto exit;
    }

    allein spielt er verrückt und meint ihm würde ein (;) fehlen. *amkopfkratz*
    Zurück zum Problem:

    Wie erreiche es das der Pointer genau den String nimmt der in den jeweiligen 50 Zeichen ausließt, wie man es zB mit datenfeld[43000][50] machen könnte.

    Wäre unendlich dankbar für Hilfe!

    Bis denne

    Markus 🙂



  • du willst bestimmt mal http://www.pronix.de/pronix-762.html lesen 🙂



  • Tja ... 4 Augen sehen mehr als zwei... hab wie wild gegooglt ... mal gucken obs klappt... 😉



  • Kann mir da vll trotzdem jemand weiterhelfen 😞 ... ich blicke da so nicht ganz durch... ich denke da würde sich jemand finden..

    Vielen dank schonmal...

    Markus



  • rundem schrieb:

    if (datenfeld==NULL)
    {
    goto exit;
    }

    Wuuuuaaahhh! Ein goto-Troll... 😮



  • 😃 Da steh ich zu...

    Hast du vll ne Idee wie das ANDERE 😉 Problem lösen kann?



  • rundem schrieb:

    😃 Da steh ich zu...

    Hast du vll ne Idee wie das ANDERE 😉 Problem lösen kann?

    wie wäre es denn wenn du das einfach als funktion aus programmierst anstatt den goto-befehl zu benutzen ? oder setz nen switch. gibts doch (oft) schönere möglichkeiten. der goto-befehl trägt in den meisten fällen wohl eher zur unlesbarkeit bei 😉



  • du versuchst mal eben so 2GB daten zu reservieren, das is nicht grad wenig oder?
    naja jedenfalls solltest du dir überlegen, wie du deine felder reservierst - du versuchst im prinzip ein riesenfeld mit 2,2mio chars zu reservieren - das is ja net der sinn. was du brauchst ist ein ptr auf ein ptr feld auf ein ptrfeld, sozusagen dein 3d array. vorgehensweise: du reserveirst ein ptr feld mit 44 ptr und zu jedem ptr wieder ein ptrfeld mit je 1000 ptr und dann zu jedem ptr ein ptr feld mit 50 chars. so würde ich es machen. es is au noch komplizierter als ich es jetzt beschrieben hab, weil du einen dreifach ptr brauchst



  • problemkind schrieb:

    ... weil du einen dreifach ptr brauchst

    sowas in der art?

    #define NUMBER_OF_STRINGS 43000
    #define SIZE_OF_STRING 50
    
    void make_pointers (char ***pointers)
    {
       int s;
       *pointers = malloc(NUMBER_OF_STRINGS * sizeof(char*));
       for (s=0; s<NUMBER_OF_STRINGS; s++)
          (*pointers)[s] = malloc(SIZE_OF_STRING+1);
    }
    
    void main (void)
    {
       char **pointers;
       make_pointers(&pointers);
    
       // test
       strcpy (pointers[NUMBER_OF_STRINGS-1], "hello pointers");
       printf ("%s\n", pointers[NUMBER_OF_STRINGS-1]);
    }
    

    😉



  • problemkind schrieb:

    du versuchst mal eben so 2GB daten zu reservieren, das is nicht grad wenig oder?

    Also bei mir sind's immer noch MB.

    problemkind schrieb:

    naja jedenfalls solltest du dir überlegen, wie du deine felder reservierst - du versuchst im prinzip ein riesenfeld mit 2,2mio chars zu reservieren - das is ja net der sinn.

    Wieso?

    problemkind schrieb:

    was du brauchst ist ein ptr auf ein ptr feld auf ein ptrfeld, sozusagen dein 3d array.

    Das ist aber kein 3D Array. Lediglich eine Repräsentation für ein dynamisches Äquivalent. Wenn man etwas als mehrdimensionales Array bezeichnen will, dann eher sowas

    int x[10][20][30];
    

    Wobei das auch nur ein einfaches Array ist, mit 10 Elementen von Typ int[20][30].

    problemkind schrieb:

    vorgehensweise: du reserveirst ein ptr feld mit 44 ptr und zu jedem ptr wieder ein ptrfeld mit je 1000 ptr und dann zu jedem ptr ein ptr feld mit 50 chars. so würde ich es machen. es is au noch komplizierter als ich es jetzt beschrieben hab, weil du einen dreifach ptr brauchst

    Du regst dich über die paar Byte Speicher auf, behandelst deinen Speichermanager aber so brutal? 🙄

    @rundem
    Du kannst deine Speicherreservierung ruhig so plain beibehalten. Ist in solchen Situationen sowieso oftmals besser, weil weniger speicherintensiv und -aufwändig. Leider hast du dann das Problem, dass du dieses Array syntaktisch nicht so behandeln kannst wie nicht-dynamische Arrays. Deshalb sieht man wohl auch oftmals den Umweg über die Zeiger, die eigentlich nur Vorteile bzgl. Einfügen, Löschen und Umsortieren bieten.
    In C++ könnte man den Speicher einfach kapseln und Operator [] überladen. In C gibt es diese Möglichkeit leider nicht. Ich würde mir deshalb etwas anderes überlegen, zB eine simple Zugriffsfunktion basteln.

    char* foo(char* datenfeld, size_t groesse, size_t wert)
    {
        return datenfeld[(groesse * 1000 + wert) * 50];
    }
    
    char* datenfeld = malloc(44 * 1000 * 50 * sizeof(char));
    char* s = foo(datenfeld, 10, 200); // datenfeld[10][200] -> damit erhaelst du zB die 50 Zeichen bei Groesse 10 und Wert 200
    

    Bietet zB den Vorteil, dass du auch ungültige Zugriffe abfangen kannst.

    Eine andere Möglichkeit, die ich mir noch vorstellen könnte, wäre ein Cast. Da bin ich mir aber momentan nicht ganz sicher, ob das eindeutig standardkonform ist. Ich wüsste zumindest erstmal nichts, was dagegen sprechen würde.

    char* datenfeld = malloc(44 * 1000 * 50 * sizeof(char));
    char (*buf)[1000][50] = (char(*)[1000][50]) datenfeld;
    char* s = buf[10][200];
    

    Ist natürlich nur möglich, wenn Grösse (1000) und die Anzahl der jeweiligen Zeichen (50) konstante Ausdrücke sind.

    Als letztes gäbe es noch VLAs.


Anmelden zum Antworten