INI Datei auslesen und als #define speichern



  • Carreck schrieb:

    int **array1=NULL;
    	array1 = (int **) malloc(a*sizeof(int *));
    	for (int i=0;i<a;i++)
    		array1[i] = (int *) malloc(b*sizeof(int));
    	const int S = sizeof(array1);
    	const int T = sizeof(array1);
    

    Das war dein Problem. sizeof funktioniert nicht wie du es hier annimmst. sizeof liefert die Größe des Typs und nicht des hinter einem Zeiger liegenden Speicherbereichs. sizeof(int**) = 4.



  • auch ohne STL(und,und...) laesst sich dann viel leichter mit dem "Spielfeld"
    arbeiten - und es ist schon eher C++, Java-artig

    #include <windows.h>
    #include <cassert>
    
    struct array_2d_t
    {
      array_2d_t(int p_width, int p_height):
      	m_width(p_width),
      	m_height(p_height),
      	m_buffer(0)
      {
        //allokieren
        m_buffer = new int[p_width*p_height];
      }
    
      ~array_2d_t()
      {
        //speicher aufrauemen
        delete[] m_buffer;
        m_buffer = 0;
      }
    
      int& at(int x, int y)
      {
        assert(x >= 0 && x < m_width);
        assert(y >= 0 && y < m_height);
        return m_buffer[x*m_width+y];
      }
    
      int width() const
      {
        return m_width;
      }
    
      int height() const
      {
        return m_height;
      }
    
      int* m_buffer; // alternativ auch std::vector<std::vector<int>> aber man soll ja noch was lernen
      int m_height;
      int m_width;
    };
    
    //eine deiner funktionen darauf umgestellt
    
    void random_array(array_2d_t& p_array) // bitte als &-referenz uebergeben
    {
      for(int i = 0; i < p_array.width(); i++) 
      { 
        for(int j = 0; j < p_array.height(); j++) 
        { 
           p_array.at(i,j) = rand() % 2;
        } 
      } 
    }
    
    int main()
    {
      int width = GetPrivateProfileInt("general","X",10,"./test.ini"); 
      int height = GetPrivateProfileInt("general","Y",10,"./test.ini"); 
    
      for(int i = 0; i < 10; ++i)
      {
        array_2d_t array(width,height);
        int v = array.at(width-1,height-1);
        random_array(array);
      }
    }
    


  • Carreck schrieb:

    void neues_array(int **A, int X, int Y)
    {
        int temp[20][20];
    

    Das ist immer noch Müll. Warum übergibst du die Parameter dynamisch und benutzt dann doch wieder statischen Größen von 20?
    Was macht dein Code, wenn in der INI mal 30 steht?

    http://ideone.com/lS8JUQ

    #define A(i,j) a[y*j+i]
    #define T(i,j) temp[y*j+i]
    #define M(i,j) maske[y*j+i]
    void random_array(int *a, int x, int y)                  
    {
    	int i, j;
    	for (i = 0; i < y; i++)
    	{
    		for (j = 0; j < x; j++)
    		{
    			A(i,j) = rand() & 1;              
    		}
    	}
    }
    
    void array_anzeigen(int *a, int x, int y)       
    {
    	int i, j;
    	for (i = 0; i < y; i++)
    	{
    		for (j = 0; j < x; j++)
    		{
    			printf("%2d", A(i,j));
    		}
    		printf("\n");
    	}
    	printf("\n");
    }
    
    void neues_array(int *a, int x, int y)
    {
    	int i, j;
    	int *temp = calloc(sizeof*a, x*y);
    	int *maske = calloc(sizeof*a, x*y);
    	memcpy(temp, a, x*y*sizeof*a);
    
    	for (i = 0; i < y; i++)
    	{
    		for (j = 0; j < x; j++)
    		{
    			if (T(i-1,j-1) == 1 && i     > 0 && j     > 0) ++M(i,j);
    			if (T(i-0,j-1) == 1 && j     > 0)              ++M(i,j);
    			if (T(i-1,j-0) == 1 && i     > 0)              ++M(i,j);
    			if (T(i-1,j+1) == 1 && i     > 0 && j + 1 < x) ++M(i,j);
    			if (T(i-0,j+1) == 1 && j + 1 < x)              ++M(i,j);
    			if (T(i+1,j-0) == 1 && i + 1 < y)              ++M(i,j);
    			if (T(i+1,j-1) == 1 && i + 1 < y && j     > 0) ++M(i,j);
    			if (T(i+1,j+1) == 1 && i + 1 < y && j + 1 < x) ++M(i,j);
    
    			if (M(i,j) > 3 || M(i,j) < 2)
    				A(i,j) = 0;
    			else if (M(i,j) == 3)
    				A(i,j) = 1;
    		}
    	}
    	free(maske), free(temp);
    }
    
    int main()
    {
    	int runde;
    	int x = 20;
    	int y = 20;
    	int *a = calloc(sizeof*a, x*y);
    	srand(time(0));
    	random_array(a,x,y);
    
    	for (runde = 1; runde < 5; ++runde, getchar())
    	{
    		neues_array(a, x, y);
    		printf(" Runde %i\n", runde);
    		array_anzeigen(a, x, y);
    	}
    
    	free(a);
    	return 0;
    }
    


  • Ich bin jetzt mal auf den Zug von llm aufgesprungen und habe folgendes gebastelt:

    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <cassert>
    #include <time.h>
    
    using namespace std;
    
    struct array_2d_t
    {
      array_2d_t(int p_width, int p_height):
        m_width(p_width),
        m_height(p_height),
        m_buffer(0)
      {
        //allokieren
        m_buffer = new int[p_width*p_height];
      }
    
      ~array_2d_t()
      {
        //speicher aufrauemen
        delete[] m_buffer;
        m_buffer = 0;
      }
    
      int& at(int x, int y)
      {
        assert(x >= 0 && x <= m_width-1);
        assert(y >= 0 && y <= m_height-1);
        return m_buffer[x*m_width+y];
      }
    
      int& temp(int x, int y)
      {
        assert(x >= 0 && x <= m_width-1);
        assert(y >= 0 && y <= m_height-1);
        return m_buffer[x*m_width+y];
      }
    
      int& maske(int x, int y)
      {
        assert(x >= 0 && x <= m_width-1);
        assert(y >= 0 && y <= m_height-1);
        return m_buffer[x*m_width+y];
      }
    
      int width() const
      {
        return m_width;
      }
    
      int height() const
      {
        return m_height;
      }
    
      int* m_buffer;
      int m_height;
      int m_width;
    };
    
    void random_array(array_2d_t& p_array)
    {
    	for (int i = 0; i < p_array.width(); i++)
    	{
    		for (int j = 0; j < p_array.height(); j++)
    		{
    			p_array.at(i,j) = rand() %2;
    		}
    	}
    }
    
    void array_anzeigen(array_2d_t& p_array)
    {
       for (int i = 0; i < p_array.width(); i++)
    	{
    		for (int j = 0; j < p_array.height(); j++)
    		{
                printf(" %d", p_array.at(i,j));
            }
            printf("\n");
        }
        printf("\n");
    }
    
    void neues_array(array_2d_t& p_array)
    {
    
    	/*int width = GetPrivateProfileInt("general","X",10,"./test.txt");
    	int height = GetPrivateProfileInt("general","Y",10,"./test.txt");*/
    	int width = 10;
    	int height = 10;
    
    	array_2d_t array(width,height);
        int temp = array.at(width-1,height-1);
        int maske = array.at(width-1,height-1);
    
        for(int i = 0; i < p_array.height(); i++)
        {
            for(int j = 0; j < p_array.width(); j++)
            {
    			p_array.temp(i,j) = p_array.at(i,j);
            }
        }
    
        for(int i = 0; i < p_array.height(); i++)
        {
    		for(int j = 0; j < p_array.width(); j++)
            {
                p_array.maske(i,j) = 0;
            }
        }
    
        for(int i = 0; i < p_array.height(); i++)
        {
            for(int j = 0; j < p_array.width(); j++)
            {
                if(p_array.temp((i-1),(j-1)) == 1 && i     > 0				  && j					 > 0) ++p_array.maske(i,j);
    			if(p_array.temp(i,(j-1))     == 1							  && j					 > 0) ++p_array.maske(i,j);
    			if(p_array.temp((i-1),j)     == 1 && i     > 0											) ++p_array.maske(i,j);
    			if(p_array.temp((i-1),(j+1)) == 1 && i     > 0				  && j + 1 < p_array.width()) ++p_array.maske(i,j);
    			if(p_array.temp(i,(j+1))     == 1							  && j + 1 < p_array.width()) ++p_array.maske(i,j);
    			if(p_array.temp((i+1),j)     == 1 && i + 1 < p_array.height()							) ++p_array.maske(i,j);
    			if(p_array.temp((i+1),(j-1)) == 1 && i + 1 < p_array.height() && j					 > 0) ++p_array.maske(i,j);
    			if(p_array.temp((i+1),(j+1)) == 1 && i + 1 < p_array.height() && j + 1 < p_array.width()) ++p_array.maske(i,j);
    
                if(p_array.maske(i,j) > 3 || p_array.maske(i,j) < 2)
                    p_array.at(i,j) = 0;
                else if(p_array.maske(i,j) == 3)
                    p_array.at(i,j) = 0;
            }
        }
    }
    
    int main()
    {
    	srand((unsigned int) time(NULL));
    	int width = GetPrivateProfileInt("general","X",10,"./test.txt");
    	int height = GetPrivateProfileInt("general","Y",10,"./test.txt");
    
        array_2d_t array(width,height);
        int v = array.at(width-1,height-1);
        random_array(array);
    
    	int runde = 1;
    	while(getchar())
    	{
    		neues_array(array);
    		printf(" Runde %i\n", runde);
    		array_anzeigen(array);
    
    		++runde;
    	}
    
    	return 0;
    
    }
    

    Er schmeißt mir jetzt in Zeile 36 folgende Fehlermeldung raus:

    Assertion failed: x >= 0 && x <= m_width-1, file i:\..., line 36
    

    Anscheinend fliegt er irgendwo außerhalb des Bereichs, oder?



  • Vermutlich in Zeile 120-127. Du solltest die Bedingungen so umstellen, dass zuerst gecheckt wird, ob der Index gültig ist und dann erst zugegriffen wird.

    BTW wieso hast du drei Funktionen (at, temp und maske), die exakt das gleiche tun? Und wieso kopierst du p_array in sich selbst, und warum baust du eine lokale Variable array, ohne sie zu benutzen? Die Logik ist dermaßen kaputt, das ist unglaublich.



  • Das array_2d_t ist schon ein guter Ansatz, aber da lassen sich einige Details verbessern. Das die Höhe und Breite wohl nie negativ werden solltest du hier unsigned int statt int benutzen. Das Gleiche gilt für die Zugriffe über den Zeilen- und Spaltenindex der Methode at , temp und maske , wobei alle Methode dasselbe tun und redundant sind. Du brauchst also nur at . Durch die Umstellung von int auf unsigned int kommst du in den assert Makros mit einem Kriterium hin:

    ...
    int& at( unsigned int x, unsigned int y )
    {
       assert( x < m_width );
       assert( y < m_height );
    
       // wer denkt sich sowas aus?
       // assert( x <= m_width -1 );
       // assert( y <= m_height -1 );
    }
    ...
    

    Wie Bashar schon erwähnt hat treten deine Speicherzugriffsverletzungen beim Zugriff auf das array auf. Deine Laufvariablen i und i in Zeile 116 bzw 118 starten bei 0 und in Zeile 120ff greifst du mit i-1 bzw. j-1 auf ungültige Speicherbereiche zu. Das Gleiche passiert beim jeweils letzten Schleifendurchlauf, da greifst du mit i+1 bzw. j+1 wiederum auf ungültige Speicherbereiche zu.



  • 1. using namespace std; ist nur für Notlösungen und schreibfaule

    du verwendest nirgends std:: und wenn dann schreib definitiv das std:: vorne drann - sonst hauen dich anständige Entwickler zusammen

    2. die temp und mask aus dem array_2d_t raus - bisher war
    es ein allgeinens 2d-int array - du spezialisiert ohne Not und Sinn direkt auf dein Problem hin (temp und mask-Methode) - so schreibt man keine Software

    ich glaube du denkst die Methoden .temp und .mask wären so eine Art Kopie des Arrays - oder? mehr falsch geht echt nicht

    3. @DocShoe - int damit er leichter Fehler anhand negativer Zahlen "erkennen"
    kann sonst lernt er auch gleich noch was int-Overflows für Effekte haben

    4. deine neues_array Funktion ist total komisch

    void neues_array(array_2d_t& p_array)
    {
        /*int width = GetPrivateProfileInt("general","X",10,"./test.txt");
        int height = GetPrivateProfileInt("general","Y",10,"./test.txt");*/
        int width = 10; //<----- warum nicht einfach p_array.width()
        int height = 10; //<----- warum nicht einfach p_array.height()
    
        array_2d_t array(width,height); // hier erzeugst du 1 neues Array
        int temp = array.at(width-1,height-1); // hier holst du IRGENDEINEN Wert
        int maske = array.at(width-1,height-1); // hier holst du IRGENDEINEN Wert
    

    5. Assertion failed: x >= 0 && x <= m_width-1, file i:\..., line 36

    ich mag asserts - die zeigen so schön die Probleme auf

    hier noch ein array_2d_t mit kopier-funktion

    #include <windows.h>
    #include <cassert>
    #include <algorithm>
    
    struct array_2d_t
    {
      array_2d_t():
        m_width(0),
        m_height(0),
        m_buffer(0)
      {
      }
    
      array_2d_t(int p_width, int p_height):
        m_width(p_width),
        m_height(p_height),
        m_buffer(0)
      {
        //allokieren
        m_buffer = new int[p_width*p_height](); // mit 0 initialisierung
      }
    
      //neues array mit inhalt des alten anlegen ala array2(array1)
      array_2d_t(const array_2d_t& p_other):
        m_width(p_other.m_width),
        m_height(p_other.m_height),
        m_buffer(0)
      {
        m_buffer = new int[m_width*m_height](); // mit 0 initialisierung
        std::copy(p_other.m_buffer, p_other.m_buffer + m_width*m_height, m_buffer);
      }
    
      //array den inhalt eines anderen zuweisen ala array2 = array1
      array_2d_t& operator= (const array_2d_t& p_other)
      {
        if (this != &p_other) // kein self-assign
        {
          delete[] m_buffer;
          m_buffer = new int[m_width*m_height](); // mit 0 initialisierung
          std::copy(p_other.m_buffer, p_other.m_buffer + m_width*m_height, m_buffer);
        }
        return *this;
      }
    
      ~array_2d_t()
      {
        //speicher aufrauemen
        delete[] m_buffer;
        m_buffer = 0;
      }
    
      int& at(int x, int y)
      {
        assert(x >= 0 && x < m_width);
        assert(y >= 0 && y < m_height);
        return m_buffer[x*m_width+y];
      }
    
      int width() const
      {
        return m_width;
      }
    
      int height() const
      {
        return m_height;
      }
    
      int* m_buffer; // alternativ auch std::vector<std::vector<int>> aber man soll ja noch was lernen
      int m_height;
      int m_width;
    };
    
    void neues_array(array_2d_t& p_altes_array, array_2d_t& p_neues_array)
    {
      p_neues_array = p_altes_array;
    }
    
    int main()
    {
      int width = 10; //GetPrivateProfileInt("general","X",10,"./test.ini"); 
      int height = 20; //GetPrivateProfileInt("general","Y",10,"./test.ini"); 
    
      array_2d_t array1(width, height);
      array_2d_t array1_copy1(array1); // kopie mit copy-ctor
      array_2d_t array1_copy2 = array1; // kopie mit assign-op
    
      //oder auch so
      array_2d_t array2;
      neues_array(array1, array2);
    
      //mit move-semantic (C++11) auch so machbar
      //array_2d_t array2 = neues_array(array1);
    }
    

    den rest musst du jetzt aber echt selber machen



  • llm schrieb:

    1. Attribute hoch!
    2. Nimm Copy&Swap
    3. Lass die Nullzuweisung nach delete



    //neues array mit inhalt des alten anlegen ala array2(array1)
      array_2d_t(const array_2d_t& p_other)
        m_width(p_other.m_width),
        m_height(p_other.m_height),
        m_buffer(0)
      {
        m_buffer = new int[m_width*m_height](); // mit 0 initialisierung
        std::copy(p_other.m_buffer, p_other.m_buffer + m_width*m_height, m_buffer);
      }
    

    =>

    //neues array mit inhalt des alten anlegen ala array2(array1)
      array_2d_t(const array_2d_t& p_other)::
        // =0 nicht nötig, Array mit zu 0 vollschreiben unnötig, Reihenfolge der Member beachten.
        m_buffer(new int[p_other.m_width*p_other.m_height]),
        m_width(p_other.m_width),
        m_height(p_other.m_height)
      {
        std::copy(p_other.m_buffer, p_other.m_buffer + m_width*m_height, m_buffer);
      }
    


  • @volkard

    1. Attribute hoch!

    ist keine class (es fehlt an private usw.) aber gehören trotzdem nicht
    zur Schnittstelle - also ist es gut wenn man die nicht sofort sieht

    2. Nimm Copy&Swap

    ich dachte etwas mehr Handarbeit könnte verständlicher sein

    3. Lass die Nullzuweisung nach delete

    ich finde ich es manchmal nett mein Objekt stärker zu invalidieren
    (als eine Art assert für z.B. fehlerhafter move-semantic implementation usw.)

    @4.

    ich wollte die kopiererei nur homogener aussehen lassen

    es fehlt noch eine const-korrekte at methode, public/private, ein paar kleine Hilfsmethoden, value_type als template Parameter usw... aber es sollte nur ein wenig besser sein - nicht gleich die volle Ladung Perfektion



  • Carreck schrieb:

    Ich bin jetzt mal auf den Zug von llm aufgesprungen und habe folgendes gebastelt:

    Nicht basteln...
    Man, Kerl! Ich dachte Du willst jetzt C machen, und auf einmal kommst Du mit noch mehr C++ um die Ecke.
    Vielleicht beendest Du mal Deinen panischen trial-and-error Modus und kommst zur Besinnung. Du bist doch nicht auf der Flucht!

    So wird das jedenfalls nix!

    PS: Happy Ausbildungsanfang! 🙂



  • llm schrieb:

    @volkard

    1. Attribute hoch!

    ist keine class (es fehlt an private usw.) aber gehören trotzdem nicht
    zur Schnittstelle - also ist es gut wenn man die nicht sofort sieht

    Das Gedasel um Schnittstellen ist absolut kein Argument. Es erhöht die Lesbarkeit ungemein, wenn man die Attribute zuerst gezeigt bekommt.

    llm schrieb:

    2. Nimm Copy&Swap

    ich dachte etwas mehr Handarbeit könnte verständlicher sein

    Aber ist nicht exception-sicher.

    llm schrieb:

    3. Lass die Nullzuweisung nach delete

    ich finde ich es manchmal nett mein Objekt stärker zu invalidieren
    (als eine Art assert für z.B. fehlerhafter move-semantic implementation usw.)

    Aber im Destruktor?! Das Attribut verschwindet eh sofort.



  • @volkard - 100% ACK

    m_buffer = 0 ist nur eine pseudo-Strategie die ich mir angewöhnt habe
    weil ich zu oft während meiner Arbeit use-after-free Bugs usw. finde (auch ohne Sanitizer/Valgrind,...) - das hilft ein wenig, ist aber wie du schon sagst völlig unnötig

    @Carreck

    nur so als Tip:

    nimm einfach deinen funktionierenden Source vom ersten Post (UNVERAENDERT)
    der mit den #defines welcher funktioniert

    dann fuegst du meine erste Version des array_2d_t oben rein
    die Kopierfunktionalität aus der neueren brauchst du gar nicht

    Ersetze stupide genau in der Reihenfolge

    1. void random_array(int A[X][Y]) -> void random_array(array2d_t& A)
    2. void array_anzeigen(int arr[X][Y]) -> void array_anzeigen(array_2d_t& arr)
    3. void neues_array(int A[X][Y]) -> void neues_array(array_2d_t& a)
    4. int temp[X][Y]; -> array_2d_t temp(X,Y);
    5. int maske[Y][X]; -> array_2d_t maske(X,Y);
    6. int A[X][Y]; -> array2d_t A(X,Y);
    7. alle Zugriffe auf X durch passendes .width()
    8. und alle Zugriffe auf Y durch passendes .heigth()
    9. und alle Array-Zugriffe mit [?][?] durch .at(?,?)

    dann sollte schonmal alles mit dem array_2d_t laufen - wenn
    der assert wieder zuschlaegt ist dein original auch schon fehlerhaft
    und muss korrigiert werden
    jetzt kannst du sehr leicht deine INI-Parameter einbauen


  • Mod

    llm schrieb:

    m_buffer = 0 ist nur eine pseudo-Strategie die ich mir angewöhnt habe
    weil ich zu oft während meiner Arbeit use-after-free Bugs usw. finde (auch ohne Sanitizer/Valgrind,...) - das hilft ein wenig, ist aber wie du schon sagst völlig unnötig

    Falls es dir nicht bekannt ist: Du verschleierst dafür andere Arten von Fehlern, wie doppelte frees. Diese würden zwar im Gegensatz zum beschriebenen Fehler kein undefiniertes Verhalten auslösen, deuten aber auf einen Logikfehler hin, der dann unentdeckt bleibt. Da dies die selbe Klasse von Logikfehlern ist wie use-after-free, ist anzunehmen, dass es auch diese Sorte in den genannten Programmen gibt.



  • llm schrieb:

    @volkard - 100% ACK

    m_buffer = 0 ist nur eine pseudo-Strategie die ich mir angewöhnt habe
    weil ich zu oft während meiner Arbeit use-after-free Bugs usw. finde (auch ohne Sanitizer/Valgrind,...) - das hilft ein wenig, ist aber wie du schon sagst völlig unnötig

    @Carreck

    nur so als Tip:

    nimm einfach deinen funktionierenden Source vom ersten Post (UNVERAENDERT)
    der mit den #defines welcher funktioniert

    dann fuegst du meine erste Version des array_2d_t oben rein
    die Kopierfunktionalität aus der neueren brauchst du gar nicht

    Ersetze stupide genau in der Reihenfolge

    1. void random_array(int A[X][Y]) -> void random_array(array2d_t& A)
    2. void array_anzeigen(int arr[X][Y]) -> void array_anzeigen(array_2d_t& arr)
    3. void neues_array(int A[X][Y]) -> void neues_array(array_2d_t& a)
    4. int temp[X][Y]; -> array_2d_t temp(X,Y);
    5. int maske[Y][X]; -> array_2d_t maske(X,Y);
    6. int A[X][Y]; -> array2d_t A(X,Y);
    7. alle Zugriffe auf X durch passendes .width()
    8. und alle Zugriffe auf Y durch passendes .heigth()
    9. und alle Array-Zugriffe mit [?][?] durch .at(?,?)

    dann sollte schonmal alles mit dem array_2d_t laufen - wenn
    der assert wieder zuschlaegt ist dein original auch schon fehlerhaft
    und muss korrigiert werden
    jetzt kannst du sehr leicht deine INI-Parameter einbauen

    Die erste Version ist insofern fehlerhaft, dass, wenn ich bei (0,0) bin und er dann -1 macht, bin ich ja definitiv in einem Speicherbereich, wo ich nicht sein kann, da er nicht belegt ist.
    Von der Logik her muss ich also "nur" die Abfrage umschreiben.
    Überprüfen, wo ich bin und dann die Felder drum rum. Macht man das am besten im Switch-Case Format?

    Ich weiß, ich bin ein bisschen schwierig.. In diesem Sinne: Danke schonmal, dass ihr mir helft..



  • @Sepp

    Du verschleierst dafür andere Arten von Fehlern, wie doppelte frees.

    du hast ja recht - ich mache es auch eher so

    m_buffer = (int*)-1;

    aber gehört hier wohl einfach nicht rein

    @Carreck

    Von der Logik her muss ich also "nur" die Abfrage umschreiben.

    der zuletzt von dir gepostete Source ist totaler Müll

    mach einfach das stupide Ersetzen GENAU SO wie in meinem letzten Post beschrieben und suche dann den Fehler in der Verarbeitung - alles andere macht einfach keinen Sinn - dein nächster Post sollte deine 1. Version mit dem array_2d_t sein - ohne sonstige Änderungen, sei einfach mal Konsequent ohne basteln



  • llm schrieb:

    mach einfach das stupide Ersetzen wie in meinem letzten Post beschrieben und suche dann den Fehler in der Verarbeitung - alles andere macht einfach keinen Sinn

    Das habe ich bereits gemacht, dementsprechend sieht der Quellcode folgendermaßen aus:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <fstream>
    #include <cassert>
    
    #define X 10
    #define Y 10
    
    struct array_2d_t
    {
    	array_2d_t(int p_width, int p_height) :
    	m_width(p_width),
    	m_height(p_height),
    	m_buffer(0)
    	{
    		//allokieren
    		m_buffer = new int[p_width*p_height];
    	}
    
    	~array_2d_t()
    	{
    		//speicher aufrauemen
    		delete[] m_buffer;
    		m_buffer = 0;
    	}
    
    	int& at(int x, int y)
    	{
    		assert(x >= 0 && x < m_width);
    		assert(y >= 0 && y < m_height);
    		return m_buffer[x*m_width + y];
    	}
    
    	int width() const
    	{
    		return m_width;
    	}
    
    	int height() const
    	{
    		return m_height;
    	}
    
    	int* m_buffer; // alternativ auch std::vector<std::vector<int>> aber man soll ja noch was lernen
    	int m_height;
    	int m_width;
    };
    
    void random_array(array_2d_t& A)               //Random Array mit X,Y erzeugen
    {
    	for (int i = 0; i < A.height(); i++)
    	{
    		for (int j = 0; j < A.width(); j++)
    		{
    			A.at(i,j) = rand() % 2;               //Füllen mit 0 / 1
    		}
    	}
    }
    
    void array_anzeigen(array_2d_t& arr)              //Random Array mit X,Y anzeigen
    {
    	for (int i = 0; i < arr.width(); i++)
    	{
    		for (int j = 0; j < arr.height(); j++)
    		{
    			printf(" %d", arr.at(i,j));
    		}
    		printf("\n");
    	}
    	printf("\n");
    }
    
    void neues_array(array_2d_t& a)
    {
    	array_2d_t temp(X, Y);
    	for (int i = 0; i < a.height(); i++)
    	{
    		for (int j = 0; j < a.width(); j++)
    		{
    			temp.at(i,j) = a.at(i,j);
    		}
    	}
    
    	array_2d_t maske(X, Y);
    	for (int i = 0; i < a.height(); i++)
    	{
    		for (int j = 0; j < a.width(); j++)
    		{
    			maske.at(i,j) = 0;
    		}
    	}
    
    	for (int i = 0; i < a.height(); i++)
    	{
    		for (int j = 0; j < a.width(); j++)
    		{
    			if (temp.at((i-1),(j-1)) == 1 && i     > 0 && j     > 0) ++maske.at(i,j);
    			if (temp.at(i,(j-1)) == 1 && j     > 0) ++maske.at(i,j);
    			if (temp.at((i-1),j) == 1 && i     > 0) ++maske.at(i,j);
    			if (temp.at((i-1),(j+1)) == 1 && i     > 0 && j + 1 < X) ++maske.at(i,j);
    			if (temp.at(i,(j+1)) == 1 && j + 1 < X) ++maske.at(i,j);
    			if (temp.at((i+1),j) == 1 && i + 1 < Y) ++maske.at(i,j);
    			if (temp.at((i+1),(j-1)) == 1 && i + 1 < Y && j     > 0) ++maske.at(i,j);
    			if (temp.at((i+1),(j+1)) == 1 && i + 1 < Y && j + 1 < X) ++maske.at(i,j);
    
    			if (maske.at(i,j) > 3 || maske.at(i,j) < 2)
    				a.at(i,j) = 0;
    			else if (maske.at(i,j) == 3)
    				a.at(i,j) = 1;
    		}
    	}
    }
    
    int main(void)
    {
    	srand((unsigned int)time(NULL));
    	array_2d_t A(X, Y);
    	random_array(A);
    
    	int runde = 1;
    	while (getchar())
    	{
    		neues_array(A);
    		printf(" Runde %i\n", runde);
    		array_anzeigen(A);
    
    		++runde;
    	}
    
    	return 0;
    }
    

    Und dennoch:Es existiert immer noch der Assert-Fehler, weshalb ich die Abfrage umschreiben muss (so denk ich mir zumindest..)



  • Das habe ich bereits gemacht

    guter Junge - jetzt machen wirs noch kurz "konfigurierbar" und dann darfst
    du deinen Fehler suchen 🙂

    1. in void neues_array(array_2d_t& a){...}
    X ersetzen durch a.width()
    Y ersetzen durch a.height()

    2. in int main(){...}

    nach srand((unsigned int)time(NULL));

    int X = GetPrivateProfileInt("general","X", 10, ini);
    int Y = GetPrivateProfileInt("general","Y", 10, ini);

    einfuegen

    #define X und Y loeschen

    dann deinen Fehler suchen und die dynamische Spielfeldgroesse geniessen



  • Und wie schon geschrieben, die Bedingungen umdrehen:

    if (i > 0 && j > 0 && temp.at((i-1),(j-1)) == 1)
    

    etc.

    Aber dieses Gemisch aus C und C++ ist schrecklich - entweder nur C (dies ist schließlich das C Subforum!) oder konsequent modernes C++.



  • #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <fstream>
    #include <Windows.h>
    #include <cassert>
    
    struct array_2d_t
    {
    	array_2d_t(int p_width, int p_height) :
    	m_width(p_width),
    	m_height(p_height),
    	m_buffer(0)
    	{
    		//allokieren
    		m_buffer = new int[p_width*p_height];
    	}
    
    	~array_2d_t()
    	{
    		//speicher aufrauemen
    		delete[] m_buffer;
    		m_buffer = 0;
    	}
    
    	int& at(int x, int y)
    	{
    		assert(x >= 0 && x <= m_height);
    		assert(y >= 0 && y <= m_width);
    		return m_buffer[x*m_width + y];
    	}
    
    	int width() const
    	{
    		return m_width;
    	}
    
    	int height() const
    	{
    		return m_height;
    	}
    
    	int* m_buffer; // alternativ auch std::vector<std::vector<int>> aber man soll ja noch was lernen
    	int m_height;
    	int m_width;
    };
    
    void random_array(array_2d_t& A)               //Random Array mit X,Y erzeugen
    {
    	for (int i = 0; i < A.height(); i++)
    	{
    		for (int j = 0; j < A.width(); j++)
    		{
    			A.at(i,j) = rand() % 2;               //Füllen mit 0 / 1
    		}
    	}
    }
    
    void array_anzeigen(array_2d_t& arr)              //Random Array mit X,Y anzeigen
    {
    	for (int i = 0; i < arr.height(); i++)
    	{
    		for (int j = 0; j < arr.width(); j++)
    		{
    			printf(" %d", arr.at(i,j));
    		}
    		printf("\n");
    	}
    	printf("\n");
    }
    
    void neues_array(array_2d_t& a)
    {
    	array_2d_t temp(a.width(), a.height());
    	for (int i = 0; i < a.height(); i++)
    	{
    		for (int j = 0; j < a.width(); j++)
    		{
    			temp.at(i,j) = a.at(i,j);
    		}
    	}
    
    	array_2d_t maske(a.width(), a.height());
    	for (int i = 0; i < a.height(); i++)
    	{
    		for (int j = 0; j < a.width(); j++)
    		{
    			maske.at(i,j) = 0;
    		}
    	}
    
    	for (int i = 0; i < a.height(); i++)
    	{
    		for (int j = 0; j < a.width(); j++)
    		{
    			if (i > 0 && j > 0 && temp.at((i - 1), (j - 1)) == 1) ++maske.at(i, j);
    			if (j > 0 && temp.at(i, (j - 1) == 1)) ++maske.at(i, j);
    			if (i > 0 && temp.at((i - 1), j) == 1) ++maske.at(i, j);
    			if (i > 0 && j + 1 < a.width() && temp.at((i - 1), (j + 1)) == 1) ++maske.at(i, j);
    			if (j + 1 < a.width() && temp.at(i, (j + 1)) == 1) ++maske.at(i, j);
    			if (i + 1 < a.height() && temp.at((i + 1), j) == 1) ++maske.at(i, j);
    			if (i + 1 < a.height() && j > 0 && temp.at((i + 1), (j - 1)) == 1) ++maske.at(i, j);
    			if (i + 1 < a.height() && j + 1 < a.width() && temp.at((i + 1), (j + 1)) == 1) ++maske.at(i, j);
    
    				if (maske.at(i, j) > 3 || maske.at(i, j) < 2)
    					a.at(i, j) = 0;
    				else if (maske.at(i, j) == 3 || maske.at(i,j) == 2)
    					a.at(i, j) = 1;
    		}
    	}
    }
    
    int main(void)
    {
    	srand((unsigned int)time(NULL));
    	int X = GetPrivateProfileInt("general", "X", 10, "./test.txt");
    	int Y = GetPrivateProfileInt("general", "Y", 10, "./test.txt");
    	array_2d_t A(X, Y);
    	random_array(A);
    
    	int runde = 1;
    	while (getchar())
    	{
    		neues_array(A);
    		printf(" Runde %i\n", runde);
    		array_anzeigen(A);
    
    		++runde;
    	}
    
    	return 0;
    }
    

    So, geht...


Anmelden zum Antworten