05.12.2024, 12:47 UhrDeutsch | English
Hallo Gast [ Registrierung | Anmelden ]

Neues Thema eröffnen   Neue Antwort erstellen
Vorheriges Thema anzeigen Druckerfreundliche Version Einloggen, um private Nachrichten zu lesen Nächstes Thema anzeigen
Autor Nachricht
Dannyboy
Titel: Max. statische Array-Größe bei C++?  BeitragVerfasst am: 01.08.2007, 01:20 Uhr



Anmeldung: 30. Jun 2005
Beiträge: 449

Hi @ all,
ich hoffe meine Verwirrung im Kopf liegt an der Uhrzeit. Mit den Augen rollen
Für einen Leveleditor lege ich eine 2D-Map an. in diese Map müssen 15.000.000 Einträge (char) hineinpassen, also Länge * Breite * Feldgröße = 3.000 * 1.000 * 5 = 15.000.000 = 15 MB Speicher. Jedes Mal krieg' ich nun 'nen Segmentation Fault / Core Dump. Um den Fehler einzugrenzen, hab' ich das Ding unter mehreren Linux-Derivaten laufen lassen ---> gleicher Fehler. Es scheitert bereits beim Anlegen des 15 MB großen Arrays, doch das sollte doch bei 512 MB RAM (is' wenig, ich weiss Winken ) kein Problem sein. Mit den Augen rollen Compilieren einfach mit "g++ test.cpp -o test".

Hier ist der Code, der bereits das Segm. Fault erzeugt.

Code:
#include <iostream>
using namespace std;

const int MAX_LEVELWIDTH  = 3000;
const int MAX_LEVELHEIGHT = 1000;

struct Sprite { char b0, b1, b2, b3, b4; };

int main (void) {
    Sprite map [MAX_LEVELWIDTH][MAX_LEVELHEIGHT]; // <--- FEHLER!!!
    cout<<"hello world"<<endl;
    return 0;
}


Lösungsvorschläge?
Greetz
DANNYBOY
 
 Benutzer-Profile anzeigen Private Nachricht senden  
Antworten mit Zitat Nach oben
doc2
Titel:   BeitragVerfasst am: 01.08.2007, 17:25 Uhr



Anmeldung: 11. Jun 2004
Beiträge: 121

Ein int hat aber 2 bzw. 4Byte reservierten Platz. Dann sind das schon 30MB oder gar 60MB. Bin auch nicht so der c++ Experte aber in deiner Struktur sind 5 Elemente (uninitialisiert?) du übergibst aber nur 2.

Schau mal strace wo es den Speicher sprengt.
 
 Benutzer-Profile anzeigen Private Nachricht senden  
Antworten mit Zitat Nach oben
Dannyboy
Titel:   BeitragVerfasst am: 02.08.2007, 00:00 Uhr



Anmeldung: 30. Jun 2005
Beiträge: 449

Es wir KEIN int übergeben, sondern 5 chars = 5 Bytes. Es sind 15 MB Speicher (vgl. Rechnung im ersten Post).

Welche zwei Werte? Es werden keine Werte übergeben, sondern ein Array mit 2 Dimensionen wird auf die 5 Byte große Struktur angelegt.

Wie dem auch sei, es scheint statisch nicht zu gehen, weil die Array-Größe scheinbar begrenzt ist, ergo werd' ich den Speicher eben dynamisch anlegen soll mir Recht sein ...


Greetz
DANNYBOY
 
 Benutzer-Profile anzeigen Private Nachricht senden  
Antworten mit Zitat Nach oben
danone
Titel:   BeitragVerfasst am: 02.08.2007, 06:59 Uhr



Anmeldung: 13. Feb 2004
Beiträge: 373

Liegt wohl daran, dass du die 3000*1000*5 Bytes auf dem _Stack_ erzeugen willst und dessen maximale Größe (8MB?) überschreitest (Stack Overflow). Leg den Kram doch einfach auf dem Heap an, dann kannste deine ganzen 512MB RAM (plus Swap) vollmachen Winken Dazu kannst du der Einfachheit halber auch einen STL vector nehmen:
Code:
#include <iostream>
#include <vector>

using namespace std;

const int MAX_LEVELWIDTH  = 3000;
const int MAX_LEVELHEIGHT = 1000;

struct Sprite { char b0, b1, b2, b3, b4; };

int main (void)
{
   vector< vector<Sprite> > map(MAX_LEVELWIDTH,MAX_LEVELHEIGHT);
   cout<<"hello world"<<endl;
   return 0;
}
 
 Benutzer-Profile anzeigen Private Nachricht senden  
Antworten mit Zitat Nach oben
Dannyboy
Titel:   BeitragVerfasst am: 02.08.2007, 12:25 Uhr



Anmeldung: 30. Jun 2005
Beiträge: 449

Zitat:
Leg den Kram doch einfach auf dem Heap an, dann kannste deine ganzen 512MB RAM (plus Swap) vollmachen Winken

In der Überschrift steht statisch. Winken
Wie legt man denn ein Array mit 2 Dimensionen auf dem Heap an?
Geschockt

Hier mal 'n Test mit int:
Code:
 int **s = new int[5][6];

... erzeugt leider ein:
Zitat:
error: cannot convert ‘int (*)[5]’ to ‘int**’ in initialization


Greetz
DANNY
 
 Benutzer-Profile anzeigen Private Nachricht senden  
Antworten mit Zitat Nach oben
danone
Titel:   BeitragVerfasst am: 03.08.2007, 07:05 Uhr



Anmeldung: 13. Feb 2004
Beiträge: 373

Oh, ja, statisch... Winken
2D-Array auf dem Heap anlegen:
Code:
int* array[MAX_LEVELWIDTH]
for(int i=0; i<MAX_LEVELWIDTH; ++i)
   array[i] = new int[MAX_LEVELHEIGHT];
// ...
for(int i=0; i<MAX_LEVELWIDTH; ++i)
   delete[] array[i];

Da ich das selber aber auch immer zu kompliziert finde (musste es nochmal nachschauen Winken ) mache ich i.d.R. ein 1D-Array und eine Methode zur Indexberechnung, in etwa so:
Code:
class Array2D
{
   public:
      int& elem(int x, int y){ return array[index(x,y)]; }
      int index(int x, int y) const{ return y*MAX_LEVELWIDTH+x; }
      int array[MAX_LEVELWIDTH*MAX_LEVELHEIGHT];
};


dann ein Objekt dieser Klasse per new erzeugen (und später per delete löschen).
 
 Benutzer-Profile anzeigen Private Nachricht senden  
Antworten mit Zitat Nach oben
Dannyboy
Titel:   BeitragVerfasst am: 03.08.2007, 17:49 Uhr



Anmeldung: 30. Jun 2005
Beiträge: 449

Hi danone,
vielen Dank für Dein Posting, nach dem ich mich nun gerichtet habe. Hab's nun voll funktionsfähig mit dynamischer Größe auf dem Heap in 2 Dimensionen und doppelter Verpointerung. Das Ding rennt: Smilie
Code:
#include <iostream>
using namespace std;

int main(void) {

unsigned int L,H;
int **array;

cout<<"Insert array-length: "; cin>>L;
cout<<"Insert array-height:  "; cin>>H;

cout<<"Trying to allocate approx. "<<L*H*sizeof(int)/1000000<<" MB of memory ... ";

array = new (nothrow) int *[L];

if (array == NULL) {
   cout<<endl<<"Could not allocate memory"<<endl;
   return 1;
}

for (int i=0; i<L; i++){
   array[i] = new (nothrow) int[H];   
   if (array[i] == NULL) {
       cout<<endl<<"Could not allocate memory"<<endl;
      cout<<"Cleaning up ... ";
      for (int x=0; x<i; x++)
         delete [] array[x];
      delete [] array;
      cout<<" done."<<endl;
       return 1;
   }
}

cout <<"done"<<endl;
      
cout<<"Cleaning up ... ";
for (int i=0; i<L; i++){
   delete [] array[i];
}
delete [] array;

cout<<"done."<<endl;

return 0;

}


Greetz
DANNYBOY
 
 Benutzer-Profile anzeigen Private Nachricht senden  
Antworten mit Zitat Nach oben
danone
Titel:   BeitragVerfasst am: 03.08.2007, 22:42 Uhr



Anmeldung: 13. Feb 2004
Beiträge: 373

wenn du's jetzt doch dynamisch benutzt, sollte man sich die Frage stellen, ob der ganze Aufwand lohnt, wenn man doch ein triviales std::vector< std::vector<int> > benutzen könnte. Vorteil: Kein Kümmern um Speicherallokation etc., übersichtlicherer Code. Nachteil: evtl. etwas mehr Overhead, allerdings glaube ich, dass die STL-Sachen schon sehr optimiert sind.

Gruß
danone
 
 Benutzer-Profile anzeigen Private Nachricht senden  
Antworten mit Zitat Nach oben
Beiträge vom vorherigen Thema anzeigen:     
Gehe zu:  
Alle Zeiten sind GMT + 1 Stunde
Neues Thema eröffnen   Neue Antwort erstellen
Vorheriges Thema anzeigen Druckerfreundliche Version Einloggen, um private Nachrichten zu lesen Nächstes Thema anzeigen
PNphpBB2 © 2003-2007 
 
Deutsch | English
Logos and trademarks are the property of their respective owners, comments are property of their posters, the rest is © 2004 - 2006 by Jörg Schirottke (Kano).
Consult Impressum and Legal Terms for details. Kanotix is Free Software released under the GNU/GPL license.
This CMS is powered by PostNuke, all themes used at this site are released under the GNU/GPL license. designed and hosted by w3you. Our web server is running on Kanotix64-2006.