Arraygröße aus Dateiangabe initialisieren



  • NDEBUG schrieb:

    Hmm, keine Ahnung wie ihr das anstellt. Bei mir führt das zu Laufzeitfehlern... 😕

    benutz einfach winzigweichtools, die bügeln alles glatt, weil die coder von denen auch so viel mist einbauen und kein bock auf fehlersuche haben *hehe*

    Getestet mit VS2008 unter C++: Testurteil läuft 🙂



  • TTP schrieb:

    ähm, die variante von NDEBUG is aber sauberer, weil sie den speicher wieder frei gibt oder nicht?

    Je mehr Einzelpointer Du hast, desto größer die Gefahr, mal ein free zu vergessen Nicht jetzt in der Schnuckelversion, aber wenn's mal etwas unübersichtlicher wird, schon.

    Hauptsache, Du vergißt kein free!



  • Deine gefundene Variante ist auch fürn Hintern. Er macht in der Schleife einen Fehler ... er müßte eigentlich einen Offset einbauen.



  • Okay dann nehm ich auf jeden fall deine

    EDIT: ist mir auch sympatischer das ding wie n richtigen array behandeln zu könn 👍



  • TTP schrieb:

    Tim schrieb:

    Bitte lesen.
    http://www.c-plusplus.net/forum/viewtopic.php?t=206606

    hab ich doch, stand doch im 3. post oder so -.-

    O.K. wenn du es schon gelesen hast, kannst du mit dem Punkt "Verstehen" weitermachen 😉



  • Wie wir ja schon in dem anderen Thread festgestellt haben wird array[x][y] -> ((array + x) + y) und durch die Dereferenzierung muß *(array + x) selber auf eine Adresse zeigen, da y nur der Offset ist. Ich weiß nicht wie ihr das macht, aber das ist mit einem malloc Aufruf nicht umsetzbar. Also ~fricky und pointercrash() zeigt mir, wie ihr das anstellt. Würde mich interessieren, denn ich denke, daß das nicht geht.



  • Tim schrieb:

    O.K. wenn du es schon gelesen hast, kannst du mit dem Punkt "Verstehen" weitermachen 😉

    Danke, ich bin gerad bei Verstehen und umschreiben so wie ich es brauche 😉
    Ich denke bis ich die Funktion Präsentieren muss, muss ich mir nochmal Pointer genauer durchlesen, also ich weiß das ein Pointer auf einen anderen zeigt und so weiter, aber hab es bisher nur zu 75% verstanden glaubig.

    NDEBUG schrieb:

    Wie wir ja schon in dem anderen Thread festgestellt haben wird array[x][y] -> ((array + x) + y) und durch die Dereferenzierung muß *(array + x) selber auf eine Adresse zeigen, da y nur der Offset ist. Ich weiß nicht wie ihr das macht, aber das ist mit einem malloc Aufruf nicht umsetzbar. Also ~fricky und pointercrash() zeigt mir, wie ihr das anstellt. Würde mich interessieren, denn ich denke, daß das nicht geht.

    Also ich brauch wirklich nur den Code in mein VS kopieren (den ich gepostet hab), dann läuft´s...

    Das heißt es ist eigentlich ein Array im Array, da ein Array ja nur ein Teilelement aufnehmen kann... ahh jetzt hab ich´s gepeilt...
    Vereinfacht gesagt:
    Array(Array(Wert1, Wert2), Array(Wert1, Wert2), Array(Wert1, Wert2), ...) richtig?



  • NDEBUG schrieb:

    Wie wir ja schon in dem anderen Thread festgestellt haben wird array[x][y] -> ((array + x) + y) und durch die Dereferenzierung muß *(array + x) selber auf eine Adresse zeigen, da y nur der Offset ist.

    void sacramento(void)
    {	
    	int far *feld;
    	int i = 20;
    	int *spalten;
    
    	*spalten = 20;
    
    	feld = malloc( sizeof(int) * i * *spalten);
    	for (i = 0; i < 20; i ++)
    		for (*spalten = 0; *spalten < 20; *spalten++)
    		 feld[i][spalten] = i * *spalten;
    }
    

    Ich überprüf' jetzt aber nix mehr, Schnellschuß mit Problemchengefahr - das Prinzip ist aber klar? 😉



    1. spalten ist n Pointer der ins Nirvana zeigt und du willst da einfach mal 20 drunter speichern?!
    2. Die Auflösung von array[x][y] funktioniert auch hier nicht!
    3. Läuft das bei dir?! Welchen Compieler verwendest du?
    4. Hast du das selber geschrieben?

    Quarkish dein Listing.



  • also mir bleibt da jedes prinzip verborgen 😉



  • NDEBUG schrieb:

    Wie wir ja schon in dem anderen Thread festgestellt haben wird array[x][y] -> ((array + x) + y)

    nee, array[x][y] ist doch (array + x + y*hoehe) oder *(array +xbreite + y).
    🙂



  • tt ... nein. Sag mal ~fricky probierst du auch den Code den du hier postest vorher?!

    // ...
    int static_array[256][256];
    *(static_array + 3 * 256 + 2) = 5;  // geht nicht
    *(*(static_array + 3) + 2) = 5;     // geht
    static_array[3][2] = 5;             // geht
    // ...
    

    Aber ich machs dir einfach. Poste mir ein listing bei dem du ein Array per malloc(höhe x breite x size) erstellst und anschließend auf ein Element per array[x][y] zugreifst.

    EDIT: Ich versteh jetzt aber auch wo dein Knoten ist. static_array ist keine Startadresse eines Arrays ... sondern ein Pointer auf eine Startadresse eines Arrays. also ist *static_array = &static_array[0][0] und dann kommt anschließend höhe x breite x size Bytes die das Array representieren. Also ginge z.B. *(*static_array + 3 * 256 + 2) = 5.



  • NDEBUG schrieb:

    tt ... nein. Sag mal ~fricky probierst du auch den Code den du hier postest vorher?!

    Also, wenn ich zwei quengelnde Kinder am Hals habe, die nörgeln, weil die Windpocken so jucken, dann ich zumindest nicht. Das vorhin war großer in Zeitnot gefertigter Käse, das hier funzt:

    void sacramento(void)
    {	
    	int i, j, back;
    	const int zeilen = 5, spalten = 10;
    
    	int *feld;
    	feld = malloc( sizeof(int) * zeilen * spalten);
    
    	if (feld)
    	{
    		back = 0;
    		for (i = 0; i < zeilen; i ++)
    			for (j = 0; j < spalten; j++)
    				feld[i * zeilen + j] = back++;
    	}
    }
    

    ... ist aber kein echtes 2D- Array, da hast Du recht. Es gibt aber einen Trick, das dem Compiler so unterzujubeln. Ich werd' heute noch ein bißchen danach suchen, wenn ich nichts finde, werd' ich morgen was basteln.



  • Also, wenn ich zwei quengelnde Kinder am Hals habe, die nörgeln, weil die Windpocken so jucken, dann ich zumindest nicht.

    Gute Besserung deinen Kindern. Aber sowas hat man ja zum Glück nur einmal im Leben 🙂



  • pointercrash() schrieb:

    void sacramento(void)
    {	
    	int i, j, back;
    	const int zeilen = 5, spalten = 10;
    
    	int *feld;
    	feld = malloc( sizeof(int) * zeilen * spalten);
    
    	if (feld)
    	{
    		back = 0;
    		for (i = 0; i < zeilen; i ++)
    			for (j = 0; j < spalten; j++)
    				feld[i * zeilen + j] = back++;
    	}
    }
    

    ... ist aber kein echtes 2D- Array, da hast Du recht. Es gibt aber einen Trick, das dem Compiler so unterzujubeln. Ich werd' heute noch ein bißchen danach suchen, wenn ich nichts finde, werd' ich morgen was basteln.

    So gehts:

    void sacramento(void)
    {   
        int i, j, back;
        const int zeilen = 5, spalten = 10;
    
        int (*feld)[spalten];
        feld = /*(int(*)[spalten])*/malloc( sizeof(int) * zeilen * spalten);
    
        if (feld)
        {
            back = 0;
            for (i = 0; i < zeilen; i ++)
                for (j = 0; j < spalten; j++)
                    feld[i][j] = back++;
        }
    }
    

    😉



  • Wilma schrieb:

    So gehts:

    void sacramento(void)
    {   
        int i, j, back;
        const int zeilen = 5, spalten = 10;
    
        int (*feld)[spalten];
        feld = /*(int(*)[spalten])*/malloc( sizeof(int) * zeilen * spalten);
    
        if (feld)
        {
            back = 0;
            for (i = 0; i < zeilen; i ++)
                for (j = 0; j < spalten; j++)
                    feld[i][j] = back++;
        }
    }
    

    😉

    Jep, so gehts. Schöne Lösung. 👍

    Gibt es dafür auch eine Lösung, wenn Zeilen und Spalten dynamisch eingelesen werden? Im Moment muß zumindest "spalten" zur Compilierzeit ja bekannt sein.



  • Ja, man nimmt einfach einen T** und alloziert einmal Spalte und dann die Zeilen, also die klassische Variante die du schon vorgeschlagen hast 😉



  • NDEBUG schrieb:

    tt ... nein. Sag mal ~fricky probierst du auch den Code den du hier postest vorher?!

    // ...
    int static_array[256][256];
    *(static_array + 3 * 256 + 2) = 5;  // geht nicht
    

    weil der typ nicht stimmt. du müsstest es so schreiben:

    *((int*)static_array + 3 * 256 + 2) = 5;
    

    es ändert aber nichts an der berechnung der adresse eines elements. bei mehrdimensionalen arrays hängt alles hintereinander im speicher, also kein pointer auf pointer auf pointer usw...

    NDEBUG schrieb:

    Gibt es dafür auch eine Lösung, wenn Zeilen und Spalten dynamisch eingelesen werden? Im Moment muß zumindest "spalten" zur Compilierzeit ja bekannt sein.

    nee, zur compile-zeit muss eine dimension (bei 2d-arrays) bekannt sein, weil der compiler damit den effektiven offset berechnen muss (siehe oben).
    🙂



  • Tim schrieb:

    Ja, man nimmt einfach einen T** und alloziert einmal Spalte und dann die Zeilen, also die klassische Variante die du schon vorgeschlagen hast 😉

    Ich stell mir vor, dass ein int-Array mit 100444 Zeilen und 5 Spalten dynamisch erzeugt werden soll. Zeilen- und Spaltenanzahl sind zur Compilezeit nicht bekannt.
    Bei der "klassischen Methode" 100445 Aufrufe von malloc() um das Array zu erzeugen und 100445 Aufrufe von free(), um den Speicher wieder freizugeben.

    Folgendes Beispiel in C++ erledigt diese Aufgabe mit einem Aufruf von new()und delete[].

    template<typename T>
    T** const new_2d(const int z, const int s) 
    {
    	T** const a = new T*[z+(z*s*sizeof(T))/sizeof(T*)+1];
    
    	for (size_t i = 0; i < z; i++)
    		a[i] = ((T*)&a[z])+i*s;
    
    	return a;							
    }
    
    template<typename T> inline void delete_2d(T** const ptr)  { delete[] ptr; }
    
    int main()
    {
    	int zeilen  = 100444;
    	int spalten = 5;
    
    	int** const array = new_2d<int>(zeilen, spalten);
    
    	array[48532][3] = 4711;
        int test = array[48532][3];
    
    	delete_2d<int>(array);
    }
    

    Mit einem Aufruf von malloc() und free() sollte das auch in C zu programmieren sein!
    😉



  • Wilma schrieb:

    Mit einem Aufruf von malloc() und free() sollte das auch in C zu programmieren sein!

    ja, weniger kryptisch und ohne pointer-auf-pointer orgien.

    // 'array' objekt
    typedef struct array2d
    {
      int *data;
      int width;
      int height;
    } array2d_t;
    
    // 'array' anlegen
    int create (array2d_t *arr, int width, int height)
    {
      arr->data = malloc (width * height * sizeof(int));
      if (arr->data == 0)
        return 0;
      arr->width = width;
      arr->height = height;
      return 1;
    }
    
    // 'array' loeschen
    void delete (array2d_t *arr)
    {
      free (arr->data);
    }
    
    // lesezugriff
    int get (array2d_t *arr, int x, int y)
    {
      return arr->data[x + arr->width*y];
    }
    
    // schreibzugriff
    void put (array2d_t *arr, int x, int y, int v)
    {
      arr->data[x + arr->width*y] = v;
    }
    
    // test
    int main (void)
    {
      array2d_t arr;
      int test;
    
      if (0 == create (&arr, 100444, 5)) // array anlegen
      {
        puts ("f*ck!!!");
        exit (0);
      }
      put (&arr, 48532, 3, 4711);   // array[48532][3] = 4711;
      test = get (&arr, 48532, 3);  // test = array[48532][3];
      delete (&arr);                // wech damit
    
      printf ("%d\n", test);
    }
    

Anmelden zum Antworten