2012-03-31 9 views
8

Ich bin neugierig, ob es möglich ist, die maximale Größe zu bestimmen, die ein Array in C++ haben kann.Programmgesteuert finden Sie die maximale statische Array-Größe in C++

#include <iostream> 

    using namespace std; 

    #define MAX 2000000 

    int main() 
    { 
     long array[MAX]; 
     cout << "Message" << endl; 
     return 0; 
    } 

Dies kompiliert ganz gut, aber dann Segfaults sobald ich es laufen (obwohl ist Array nicht tatsächlich referenziert). Ich weiß, dass es auch die Array-Größe ist, denn wenn ich es auf 1000000 ändere, läuft es gut.

Also, gibt es einige definieren irgendwo oder eine Art zu haben #define MAX MAX_ALLOWED_ARRAY_SIZE_FOR_MY_MACHINE_DEFINED_SOMEWHERE_FOR_ME?

Ich brauche das eigentlich für nichts, diese Frage ist der Neugierde wegen.

+0

Sie wollen nur maximale Array-Größe im Stapel verstehen? Vielleicht funktioniert Rekursion dann für Sie? nicht in einem einzigen Array, sondern in kombinierter Form? – tartar

+2

@tar Was hat Rekursion damit zu tun? –

+0

Dieser Beitrag beantwortet Ihre Frage nicht, sollte aber eine interessante Lektüre sein, da es sich um das gleiche seg-Fehlerproblem handelt: http://stackoverflow.com/questions/851122/large-2d-array-gives-segmentions-fault –

Antwort

10

Es gibt keine Möglichkeit, dies statisch zu bestimmen, weil die tatsächliche Grenze hängt davon ab, wie viel Stapelspeicher Thread gegeben wurde. Sie könnten einen neuen Thread erstellen, ihm einen 10-Megabyte-Stack zuweisen, und Sie könnten ein entsprechend größeres lokales Array zuweisen.

Die Menge, die Sie auf dem Stapel zuweisen können, hängt auch davon ab, wie viel bisher bereits verwendet wurde.

+0

Das macht Sinn, ich denke, ich verstehe nicht so gut den Unterschied zwischen wie statische Arrays und dynamische Arrays in Bezug auf die Speicherzuweisung zur Laufzeit behandelt werden – SirGuy

+3

Wenn Sie eine lokale Variable deklarieren, wird der Speicherplatz für das gesamte Array von der zugewiesen Stapelspeicherplatz (dies ist im Gegensatz zu einigen anderen Sprachen wie Java). Wenn Sie etwas außerhalb einer Funktion als global deklarieren, richtet der Linker die Speicheradressen so ein, dass der Speicherplatz vorhanden ist, noch bevor das Programm gestartet wird. Der Stack hat eine begrenzte Größe (normalerweise 1 Megabyte auf einem modernen Desktop-Betriebssystem, kann jedoch sehr unterschiedlich sein), während der statische verfügbare Speicherplatz der gesamte Anwendungsadressraum des Computers ist (2 GB oder so auf einem 32-Bit-System). –

+0

Gibt es Leistungsunterschiede zwischen diesen beiden Speichertypen? Außerdem verwenden _all_ Programme denselben statischen Speicherplatz, auch wenn sie nicht ausgeführt werden? Gibt es etwas, das im statischen Raum geteilt wird, oder wenn du eine Zillion Programme installierst, könntest du einfach ausgehen? Ich vermute, Probleme damit kommen dann nicht oft vor. – SirGuy

4
void foo(int level){ 
int dummy[100]; 
cerr<<level<<endl; 
foo(level+1); 
} 

Dann können Sie vielleicht die letzte gedruckte Ebene mit 400 Bytes multiplizieren. Rekursive Aufrufe belegen den größten Teil des Stack-Platzes, aber Sie können eine Untergrenze erreichen. Ich vermisse hier vielleicht etwas Verständnis von Speicherverwaltung, also offen für Korrekturen.

Also das ist, was ich auf meinem Rechner mit variierenden Dummy-Array-Größe bekam.

level array size stack total 
24257  100  9702800 
2597 1000  10388000 
    260 10000  10400000 
    129 20000  10320000 
    64 40000  10240000 
    25 100000  10000000 
    12 200000  9600000 
+0

Ich verstehe jetzt, was Sie vorher meinten, danke – SirGuy

+0

Ich spielte mit dieser Lösung für zunehmende Größe von Ganzzahl-Array. Nur um die zusätzliche Belastung der Funktionsaufrufe bei jedem Schritt zu eliminieren. Das Maximum, das ich bekommen habe, ist, wenn die Größe des Arrays 10000 ist und die maximale Stackgröße auf meinem Rechner (Ubuntu 10.04) 10400000 Bytes ist. – tartar

+0

Vorsicht bei der Tail-Call-Optimierung hier. –

1

Bitte lesen Sie this, um die Einschränkungen zu verstehen, die von Hardware und Compiler festgelegt werden. Ich denke nicht, dass Sie einen MAX-Wert festlegen können, damit Sie ihn sofort verwenden können.

2

Die meisten innerhalb von Funktionen deklarierten Variablen werden auf the stack zugewiesen, was im Grunde genommen ein Speicherblock mit fester Größe ist. Der Versuch, eine Stapelvariable zuzuweisen, die größer ist als die Größe des Stapels, verursacht eine stack overflow, woraus der Segfault verursacht wird.

Oft ist die Größe des Stapels 8 MB, so, auf einer 64-Bit-Maschine, long max[1000000] Größe hat 8*1000000 < 8MB (der Stapel „safe“), aber long max[2000000] hat Größe 8*2000000 > 8MB, so dass der Stapel überläuft, und das Programm segfaults.

Auf der anderen Seite versetzt die dynamische Zuordnung des Arrays mit malloc den Speicher in the heap, die im Grunde unbegrenzt ist (4 GB auf einer 32-Bit-Maschine, 17.179.869.184 GB auf einer 64-Bit-Maschine).

Verwandte Themen