Fehlermeldung ab bestimmter Arraygröße



  • Hallo,
    ich bin gerade beim Lernen von C++. Jetzt habe ich einen Fehler und verstehe nicht genau, wieso der angezeigt wird.
    Ich habe ein 2D-Array, das an eine Funktion übergeben wird. Die Größe das Arrays wird von einer Konstanten, die im Präprozessor definiert wird, festgelegt.
    Jetzt habe ich mit verschiedenen Größen des Arrays rumgespielt und sobald die Arraygröße größer als 720 wird erscheint der Fehler:
    Process returned -1073741571 (0xC00000FD)
    Nach Google soll das ein stack overflow Problem sein.
    Hier ein Beispiel wie es bei mir aussieht:

    #define SIM_SIZE 721
    
    void funktion(int sim_field[SIM_SIZE][SIM_SIZE])
    {
         //Aktion
    }
    
    int main()
    {
         int sim_field[SIM_SIZE][SIM_SIZE] = { 0 };
         funktion(sim_field);
    
         return 0;
    }
    

    Vielleicht fällt Euch etwas auf.
    Schöne Grüße
    Stefan



  • Ja, jeder Thread hat einen Stack bestimmter Größe, auf dem er lokale Variablen, Rücksprungadressen usw. ablegen kann. Wenn du jetzt Variablen drauf ablegst, die größer als der Stack sind, dann fliegt dir dein Programm um die Ohren.
    Dein Array ist 721 x 721 x sizeof( int ) Bytes groß, das sind bei 32bit integer 2.079.3640 Byte und das sprengt den Stack.

    Und wo du gerade schreibst, dass du mit C++ anfängst:
    Deine Art Arrays zu benutzen macht man in C, C++ bietet da bessere Möglichkeiten, aber das ist ein anderes Thema. Stichworte sind std::vector und array to pointer decay.



  • @JohnD
    Naja, 2D Array von Int mit 720 x 720 Feldern ist jetzt nicht ganz klein. bei 720 * 720 * 4 (nehmen wir mal 4 Byte pro int an), haben wir 2073600 Byte Speicher, der da auf dem stack benötigt wird. Das sind etwas über 2 MB, wie groß der Stack ist, denn du verwenden darfst hängt von deinem System und deinen Einstellungen ab.

    Ich würde dir zu einem std::vector raten, der alloziert den Speicher dynamisch (also auf dem Heap). Da bist du nur von deinem Arbeitsspeicher begrenzt .

    Edit: @DocShoe war schneller.



  • OT:

    @JohnD sagte in Fehlermeldung ab bestimmter Arraygröße:

    ich bin gerade beim Lernen von C++

    Sieht eher nach schlechtem C aus. Womit lernst du?



  • Danke für die schnellen Antworten.
    Ich habe vorher ein bisschen Python gemacht und da ist es nie ein Problem gewesen ein Array mit 1000x1000 Plätzen anzulegen.
    Während der Laufzeit soll die Größe des Arrays nicht geändert werden. Vektoren habe ich für zwei "Listen" eingefügt, bei denen der Inhalt und die Länge des Vektors sich während der Laufzeit verändert.
    Das Array soll eigentlich eine Oberfläche mit möglichen Absorptionsplätzen für Atome darstellen.
    Wie ist es denn möglich ein Array mit z.B. 1000x1000 oder mehr Plätzen zu erstellen?

    @manni66
    Bisher orientiere ich mich an Dokumentationen oder Tutorials aus dem Internet. In der Uni hatte ich mal einen Grundkurs für das Programmieren aber mehr nicht.

    edit:
    Ich habe es jetzt mit einem "2D" Vektor versucht. Ich habe einen Vector genommen und ihn mit der Anzahl von SIM_SIZE null Vektoren gefüllt. Und die Übergabe an eine Funktion mach ich mit einer Referenz des Vektors.

    #define SIM_SIZE 721
    
    void funktion(vector <vector<int>> &sim_field)
    {
         //Aktion
    }
    
    int main()
    {
         vector < vector<int> > sim_field(SIM_SIZE,vector<int>(SIM_SIZE, 0));
         funktion(sim_field);
    
         return 0;
    }
    

    Das Programm läuft jetzt ohne stack overflow aber die Laufzeit hat sich dadurch aber ein wenig verlängert.

    Schönen Gruß
    Stefan


  • Mod

    Was du in Python als List kennst (das meinst du doch mit "Array", oder?), ist eher so etwas wie ein Vector. Daher wird dir hier auch Vector für deine Zwecke empfohlen. Ein C++-Array entspricht (semantisch) eher einem Python Tuple, aber auch das passt (von der technischen Umsetzung her) nicht so ganz.

    Entsprechend ist ein Vector von Vectoren auch nicht wirklich ein 2D-Rechteck, sondern eine Liste von (beliebig langen) Listen. Das kann zwar auch eine Rechteckform annehmen, aber Flexibilität zu beliebigen Listen kostet durchaus Performance. Daher macht man für Probleme, die feste NxM Dimensionen verlangen, stattdessen entweder einen Vector<Array<M>> (wenn M fest ist), oder einen Vector(N*M) bei dem man sich die Indizes zur Laufzeit selber ausrechnet (wenn M flexibel ist). Das ist dann auch beides genau so schnell wie ein Array von Arrays.

    PS: Mit "Array" in C++ meine ich natürlich std::array aus der Standardbibliothek, nicht deine C-Arrays, die du hier benutzt. Hol dir lieber ein vernünftiges Lehrbuch, als aus komischen Internetquellen zu lernen. Die meisten lehren nämlich C++ als ein (schlechtes!) C mit cout.



  • Hab vor einiger Zeit mal nen Thread zu 2D Arrays aufgemacht, vllt hilft dir das.
    2D Array


  • Gesperrt

    @DocShoe sagte in Fehlermeldung ab bestimmter Arraygröße:

    Hab vor einiger Zeit mal nen Thread zu 2D Arrays aufgemacht, vllt hilft dir das.
    2D Array

    Ja daran erinnere mich auch. Bin daran ein data_table mit std::variant zu implementieren, darum wird dafür C++17 benötigt. Die Version die ich brauche ist spezialisierter als das untere Beispiel. Es fehlen auch noch Methoden um die Spalten- und Reihenanzahl dynamisch verändern zu können.

    Auch die Beispielversion ist etwas spezialisiert, da sie nur für bestimmte Typen implementiert ist, aber es dürfte aber wenig Aufwand kosten, es für mehr oder/und andere Typen zu implementieren.

    #include <vector>
    #include <string>
    #include <stringstream>
    #include <variant>
    #include <type_traits>
    
    template<typename Ty>
    struct VisitDataTable
    {
    	template<typename = typename std::enable_if<!std::is_same<Ty, double>::value>::type>
    	double operator()(const double& variable) const
    	{
    		return variable;
    	}
    
    	Ty operator()(const Ty& variable) const
    	{
    		return variable;
    	}
    
    	std::string operator()(const std::string& variable) const
    	{
    		return variable;
    	}
    };
    
    
    
    template<typename Ty>
    class DataTable
    {
    public:
    
    	// Avoids double type duplicate 
    	// for variant template argument
    	using U = typename std::conditional<
    		std::is_same<Ty, double>::value,
    		std::variant<Ty, std::string>,
    		std::variant<Ty, double, std::string>
    	>::type;
    
    	DataTable() :
    		number_columns(0),
    		number_rows(0),
    	{}
    
    	void SetSize(size_t number_columns, size_t number_rows)
    	{
    		this->number_columns = number_columns;
    		this->number_rows = number_rows;
    
    		data.resize(number_columns * number_rows);
    	}
    
    	U& GetVariantRef(size_t column, size_t row)
    	{
    		return data[row * number_columns + column];
    	}
    
    	const U& GetVariantRef(size_t column, size_t row) const
    	{
    		return data[row * number_columns + column];
    	}
    
    	std::string GetString(size_t column, size_t row) const
    	{
    		std::stringstream stream;
    
    		auto variant = GetVariantRef(column, row);
    
    		std::visit([&stream](auto& variable)
    			{
    				stream << variable;
    			}, variant);
    
    		return stream.str();
    	}
    
    	size_t GetColumnByName(const std::string& name) const
    	{
    		size_t column = 0;
    		for (size_t index = 0; index < number_columns; ++index)
    		{
    			if (std::get<std::string>(data[index]) == name)
    			{
    				column = index;
    			}
    		}
    		return column;
    	}
    
    	std::vector<Ty> GetColumnData(const std::string& name) const
    	{
    		size_t column = GetColumnByName(name);
    		std::vector<Ty> column_data(GetNumberRows());
    		for (size_t index = 0; index < GetNumberRows(); ++index)
    		{
    			column_data[index] = std::get<Ty>(GetVariantRef(column, index));
    		}
    		return column_data;
    	}
    
    	size_t GetNumberRows() const
    	{
    		return number_rows;
    	}
    
    	size_t GetNumberColumns() const
    	{
    		return number_columns;
    	}
    
    private:
    
    	size_t number_columns;
    	size_t number_rows;
    
    	std::vector<U> data;
    };
    

Anmelden zum Antworten