Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » allocierter Speicher für 2d Array nicht eindeutig

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
11.04.2003, 12:49 Uhr
Crazy-X



Hi,

Ich arbeite im Dos Modus (reines Dos) und brauche für einen Bildschrim Speicher ein relativ Großes 2D Array: mind. 640x480.

Das Array sollte auch einfach an eine Funktionen übergeben werden können und per [x][y] Operator angesprochen werden. Im Internet habe ich jetzt folgendes gefunden:

unsigned short (*screen)[640];
screen = (unsigned short (*)[640]) malloc(sizeof(unsigned short) * 640 * 480);

Das ganze lässt sich ohne Probleme kompilieren. In einer Schleife setzte ich dann alle Elemente des Arrays auf 0 und dann sind auch alle 0.

Setzte ich jetzt aber screen[0][0] auf 9 werden auch noch folgende Elemente auf 9 gesetzt:
51 / 128; 102 / 256; 153 / 384; 256 / 0; usw.

Was läuft schief? Als Compiler benutze ich Borland C++ 5.01!

TIA

©®azy-X
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
11.04.2003, 12:58 Uhr
~0xdeadbeef
Gast


Hm. Eigentlich dürfte der Code garnicht laufen. Schau mal hier:

C++:
unsigned short (*screen)[640];


Das erzeugt ein Array von 640 unsigned short pointern. Damit ist screen konstant, das heißt, die Anweisung

C++:
screen = (unsigned short (*)[640]) malloc(sizeof(unsigned short) * 640 * 480);


funktioniert überhaupt nur zufällig, weil der Borland-Compiler das scheinbar nicht richtig rafft. Was dabei im Endeffekt genau passiert, ist schwierig zu beurteilen. Wie dem auch sei, es gibt vernünftigere Wege, das ganze zu managen. Das sinnvollste wäre wohl folgendes:

C++:
unsigned short screen[640][480];

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
11.04.2003, 13:02 Uhr
~Heiko
Gast


Versuch mal den Speicher so zu allokieren:


C++:
unsigned short **screen;
screen=(unsigned short**)malloc(640*sizeof(unsigned short*));
for(int j=0;j<640;j++) screen[j]=(unsigned short*)malloc(480*sizeof(unsigned short));




vielleicht funzt es ja dann
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
11.04.2003, 13:12 Uhr
~dirweis
Gast


@Heiko
ich glaube, die schleife ist überflüssig

@crazy-x
deklariere mal so, wie es beef vorschlägt und alloziiere danach mal mit
C++:
screen=(unsigned short int**)malloc(640*480*2);


kann mir keinen grund vorstellen, warum das nicht tun sollte. und free(); nicht vergessen - ich sags nur.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
11.04.2003, 13:13 Uhr
~Heiko
Gast


Ich war wohl ein bischen zu spät.

Um Verwirrungen zu vermeiden: Wenn du vorher weisst wie gross dein Array sein soll (also 640*480) dann ist die Lösung von 0xdeadbeef
natürlich die bessere.

Ich hatte nur gedacht, falls du erst zur Laufzeit weisst wie gross dein Array sein soll. (Du hattest ja geschrieben: mind. 640x480)
solltest du meine Lösung verwenden und dann ensprechent der von dir gewünschten Grösse den Speicher allokieren lassen
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
11.04.2003, 13:17 Uhr
virtual
Sexiest Bit alive
(Operator)


Ich bin jetzt nicht so der dolle (DOS) Programmierer, aber war es nicht so, daß die einzelnen Zeilen bei 640x480 einfach hintereinader im Speicher stehen? In diesem Falle wäre Beefies Lösung Heikos jedenfalls vorzuziehen, weil die machen ja schon unterschiedliche Sachen:
Bei beefies Lösung kann man einfach mit dem memcpy den Speicher in den Video RAM kopieren oder daraus ziehen, wohlgemerkt mit einem Befehl!. Bei Heikos lösung habe ich
1. Mehr Speicherverbauch: (Beefy: 640*480 Bytes+Einige Bytes zur Heapveraltung; Heiko: 640*480 Bytes + (481* Einige Bytes zur Heapverwaltung) + 640*sizeof(void*); macht also Unterschied von mehreren KBytes).
2. Mich begleiten die Schleifen immer, egal was ich tue. Bei Kopieren, beim Freigeben, Beim Belegen, beim Vergleichen.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
11.04.2003, 13:25 Uhr
~Heiko
Gast


@virtual
ja hast recht. Vergesst meine Lösung
Ich persönlich benutze auch nie mehrdimensionale arrays, sondern immer nur eindimensionale Arrays (damit gibt es das dumme Schleifenproblem erst gar nicht) aber Crazy-X wollte ja ein 2d-array haben.

Da ich erst seit nem halben Jahr programiere wirst du mir den Fehler sicher verzeihen. Ich wusste ja nicht das sich gleich alle Forumsgenies auf die Beantwortung dieser Frage stürzen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
11.04.2003, 13:45 Uhr
Crazy-X



Hi,

Erstmal schonmal Danke für eure super Hilfe.

1. Ein "unsigned short screen[640][480];" wäre ja wohl das naheliegendste. Leider meckert da mein Compiler: "Array Size to large".

2. @Heiko: Die Lösung funktioiert soweit ja schonmal. Nur aber habe ich dann ein screen[480][640]. Also die Indiezes vertauscht. Müsste das nicht funktionieren, bei der allocation die 480 & 640 zu vertauschen?
Aber wenn ich das so mache, wird meine Anwendung wegen eines unzulässigen Zugriffs beendet.

@Virtual:
So was habe ich schon bei Programmierungen für den Mode 13h gesehen. Da legen, die soweit ich das kapiert habe ein pointer Array an, das direkt auf den Video RAM zeigt. In wie weit das aber im BGI Modus, mit dem ich zur Zeit arbeite, funktioniert weis ich nicht.

Aber da ich das ganze sowieso evtl. mal im Mode 13h laufen lassen will, wäre es schon nicht schlecht einen zusammen hängenden Speicher für mein Screen Array zu allocieren.

Und wenn ich auch erst zur Laufzeit wüsste wie groß mein Array werden muss, wäre das auch nicht schlecht. Dann kann man nämlich auch verschiedene Auflösungen wählen lassen.

TIA

©®azy-X
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
11.04.2003, 14:05 Uhr
~Heiko
Gast


Dein erster Wert sollte doch x und der zweite y sein oder?
Wenn x von 0-639 gehen soll und y von 0-479
dann müsste das so wie ich den Code geschrieben hatte richtig sein.


C++:
screen=(unsigned short**)malloc(640*sizeof(unsigned short*));


legt ein unsigned short*-Pointerarray von 640 Pointer an.


C++:
for(int j=0;j<640;j++) screen[j]=(unsigned short*)malloc(480*sizeof(unsigned short));


weisst jedem dieser 640 Pointer ein array der grösse 480 zu.
damit wäre dann der Zugriff [x][y] ([0..639][0..479])

es müsste eigentlich richtig sein oder was sagen die anderen dazu?

wenn du bei der Allocation die beiden werte vertauschen willst, darfst du aber nicht vergessen auch den Wert in der Schleife zu ändern.


das mit hintereinander in den Speicher packen wird wohl nich klappen, wenn dein compiler schon bei unsigned short screen[640][480] gemeckert hat.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
11.04.2003, 14:26 Uhr
~Crazy-X
Gast


Hmm,

Wenn ich genau so allociere funktioniert folgender Code nicht:

C++:
   for (x = 0; x < 640; x++)
       for (y = 0; y < 480; y++)
           screen[x][y] = 0;



Die Anwendung wird dann wegen eines unzulässigen Zugriffs beendet. Vertausche ich aber bei screen[y][x] funktioniert alles einwendfrei.

Naja, aber im Grunde ist das ja egal...

Wird bei unsigned short screen[640][480]; das ganze nicht eigentlich in den Stack gelegt?! Dann ist ja eigentlich klar, dass der Compiler meckert. Aber warum sollte das dann nicht funktionieren mir ein screen[640][480] im heap zu allocieren?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: