Willkommen ~Gast!
Registrieren || Einloggen || Hilfe/FAQ || Staff
Probleme mit der Registrierung im Forum? Melde dich unter registerEin Bild.
Autor Beitrag
000
20.11.2002, 13:27
[HUI]-Tiger-



Hi,

ich habe folgendes Problem:
ich will eine 2d map in ein 2dimensionales array einlesen.
Dafür unnötig speicher verbraten wäre ja sinnlos (also z.B. gleich char[256][256] definieren)
Ich hab dann folgende Methode gefunden:
Quellcode:
char *pCharArray = NULL;
pCharArray = (char*)malloc(iAnzahlderFelder*sizeof(char));

geht das auch für ein zweidimensionales Array ?
Oder würdet ihr die Mapdaten ganz anders speichern ?

--

.-.-.-.
cya Tiger

zum Seitenanfang zum Seitenende Profil || Suche
001
20.11.2002, 14:16
King of Darkness



ich würde sagen probier es aus ;)

aber vieleicht wenn es ein grösseres projekt is wo maps unterschiedlich gross sind würde ich ne verketete liste nehmen ... weis nich obs sin macht

aber wenn maps immer gleich gross sind kannste doch ne feste grösse nehmen

und mal nochwas char für ne map oder is das DOS wo du dann mit den ╝ ...

was ich aber auch nich verstehe wie willst du aus einem zeichen einen array machen ?( char *pCharArray = NULL; ) das ist doch nir 1 speicherplatz

wie gesagt nimm ne verkette liste die dürfte eigendlich gehn

--

Coding Center --- Tutorials über Programmierung und andere Themen
Amazon Preisbeobachung mit Preisalarm

zum Seitenanfang zum Seitenende Profil || Suche
002
20.11.2002, 15:38
Archangel



ich würds ja so machen:

pCharArray = (char *)malloc(iAnzahlFelder);

und dann auf die einzelnen felder zugreifen mit:

int 2dindex(int x, int y)
{
return y * iGroesseY + x;
}

--

Mar 01 01:10:13 <voice> jo
Mar 01 01:10:40 <voice> bis dann ^^
Mar 01 01:11:20 <Archangel> jo
**** ENDING LOGGING AT Tue Mar 1 01:58:13 2005

zum Seitenanfang zum Seitenende Profil || Suche
003
20.11.2002, 16:23
[HUI]-Tiger-



map haben keine feste Größe, deshalb ja...

@Archangel: ja, ich werde dann alles in ein normales array werfen.
MGS ist das geilste Game ever !!! *g*

@KoD: is net DOS...ich hab mein system nur so:
auf der map ist 0 erde, 1 gras, A ein gebäude und so hat eben alles ein Zeichen aus dem ASCII-System. Meine Map braucht dann weniger Speicherplatz wenn ich es als char auswerte, denn z.B.
'A' braucht 1 byte aber '255' schon drei und das ist ja unnötig...

wenn ich ein Array möchte darf ich ja aber nicht char *pCharArray[x][y] machen sonst bekommt ich ja ein Array mit pointern oder nicht ?

also Quellcode:pCharArray = (char*)malloc(iAnzahlderFelder*sizeof(char));
macht das ganze zu einem eindimensionalem array, so steht das zumindest auf der page die ich gefunden hab.

--

.-.-.-.
cya Tiger

zum Seitenanfang zum Seitenende Profil || Suche
004
20.11.2002, 16:37
[RMen]OneStone



Das mit dem mehreren Dimensionen stimmt, aber ich würde einfach nen unsigned int Array machen, dann kannst du mehrere Millionen verschiedener Terrain-Typen machen und es ist Prozesor-"Optimiert" (bit alignment).

Quellcode:{
  unsigned int *pnMap = 0;

  if(!(pnMap = malloc(nWidth * nHeight * sizeof(unsigned int))))
    return 0xFF; //or whatever to return on error
}

--

georg-wicherski@pixel-house.net | http://www.pixel-house.net/ - Coding Resource| http://www.google.de/

zum Seitenanfang zum Seitenende Profil || Suche
005
20.11.2002, 18:46
[HUI]-Tiger-



des hat was @OneStone ;)
...thx an alle !

--

.-.-.-.
cya Tiger

zum Seitenanfang zum Seitenende Profil || Suche
006
21.11.2002, 00:22
Leviathan



muss da nicht ein unsigned int * -cast hin? ich glaube nicht jeder compiler nimmt den code so an.

Quellcode:{
  unsigned int *pnMap = 0;

  if(!(pnMap = (unsigned int*)malloc(nWidth * nHeight * sizeof(unsigned int))))
    return 0xFF; //or whatever to return on error
}

den wert an einer postition x y im array bekommst du so (breitenposition x, längenpostition y):

Quellcode:
*(pnMap+x*nHeight+y)

natürlich muss dafür x<=nWidth und y<=nHeight sein.

--

Entities: HL | HL²
Kompilierfehler
r_speeds | mehr über r_speeds

zum Seitenanfang zum Seitenende Profil || Suche
007
21.11.2002, 08:14
King of Darkness



ok stimmt trotzdem würde ich da ne verkettete liste machen, nimmt nur so viel speicher wie es braucht und ist eigendlich auch recht schnell

--

Coding Center --- Tutorials über Programmierung und andere Themen
Amazon Preisbeobachung mit Preisalarm

zum Seitenanfang zum Seitenende Profil || Suche
008
21.11.2002, 14:26
Prefect



OMFG

Einstein: ein char ist per Definition ein Byte groß, und ein Byte ist auf praktisch jedem Prozessor ein "native"-Datentyp.

King of Darkness: Nein, eine verkette Liste ist eine absolut dumme Idee, weil sie _viel_ zu viel Speicher verbraucht. Bei der vernünftigen Methode (= 2D-Array mit y*w + x in einem 1D-Array codiert) benötigst du (Anzahl der Felder * sizeof(felddaten)) Bytes. Bei einer vierfach Linked List (in x- und y-Richtung) brauchst du (Anzahl der Felder * (sizeof(felddaten)+4*sizeof(void*))) Bytes. Wenn du nur ein Byte pro Feld brauchst, dann ist daß das 17-fache an Speicherverbrauch!
Abgesehen davon ist Random Access auf Linked Lists sehr viel langsamer als auf einfache Arrays.

cu,
Prefect

--

Widelands - Gemütliche Aufbaustrategie, Free Software
Noch ein Blog - Lerne, wie die Welt wirklich ist, aber vergiss niemals, wie sie sein sollte.

zum Seitenanfang zum Seitenende Profil || Suche
009
21.11.2002, 14:54
[RMen]OneStone



Prefect: Leider gibt es noch keine [sarkasmus] oder [ironie]-Tags, sonst hättest du meinen Post warscheinlich anders verstanden... (hab ja schon verscuht das mit den "" deutlich zu machen) ;o]

Leviathan: Das mit dem cast stimmt, aber das rausfinden einer Position geht so einfacher (<- Ansichtssache): pnMap[nX * nWidth + nY]

--

georg-wicherski@pixel-house.net | http://www.pixel-house.net/ - Coding Resource| http://www.google.de/


Dieser Beitrag wurde am 21.11.2002 um 14:54 von [RMen]OneStone bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
010
22.11.2002, 00:20
Leviathan



@onestone: hmm hast recht, ist einfacher, hätte ich eigentlich acuh drauf kommen können. das führt aber die gleiche zeigerarithmetische operation aus wie mein code, nur eben anders formuliert. meins ist das, auf das man kommt, wenn man die position eines wertes im speicher herleitet, deins ist das selbe für tippfaule umformuliert (ist auch nicht so fehleranfällig wie meins).

das cast iat afaik compilerabhängig, da malloc ein void* zurückgibt, also einen zeiger auf irgentwas (muss nur eine variable sein, ein funktionszeiger sieht anders aus). den muss man natürlich entsprechend umwandeln, da man ja schlecht die ganze zeit mit einem zeiger unbestimmten typs arbeiten kann und ihn dann auch noch dereferentiert.

hier würde ich auch keine linked list nehmen, das braucht, wie perfect schon geschrieben hat, mehr speicher, ist langsamer (eine liste abwandern dauert wesentlich länger als sich den zeiger zusammenzuaddieren und zu -multiplizieren) und ausserdem wesentlich aufwändiger zu programmieren.
per einfacher speicherreservierung braucht man eine anweisung zum erstellen (reservieren von speicher), eine für den zugriff und eine zum speicher freigeben (nicht vergessen, zu jedem malloc/calloc/realloc gehört ein free oder realloc, sonst können speicherlücken auftreten, was zu abstürzen führen kann aber nicht muss, also ein laufzeitfehler, der schwer zu finden ist, da er nicht immer auftritt).

:edit:
hier nochmal den code:

Quellcode:
int mapwidth=256;    //natürlich können hier auch andere zahlen stehen
int mapheigth=512;

/***** feld initialisieren *****/
char * pnMap=0;

if(!(pnMap=(char*)calloc(mapwidth*mapheigth,sizeof(char))))
{
    //fehler: nicht genug speicher vom betriebssystem bereitgestellt
}

/***** arbeiten mit dem feld *****/
//...
*(pnMap+x*nHeight+y)=25;
//...
cout<<pnMap[x*mapwidth+y];
//...

/***** feld wieder aus dem speicher entfernen *****/
free(pnMap)

--

Entities: HL | HL²
Kompilierfehler
r_speeds | mehr über r_speeds


Dieser Beitrag wurde am 22.11.2002 um 00:27 von Leviathan bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche