Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

cFx

Frischling

  • »cFx« ist der Autor dieses Themas
  • Private Nachricht senden

1

17.12.2015, 13:23

2D dynamisches Array

Hey zusammen!

Ich bastel gerade an meinem ersten kleinen Konsolenspiel, um all die gelernten Sachen zu vertiefen.
Hier meine derzeitigen Code-Schnipsel(WIP):


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main()
{
        // Map aufrufen und in pMap speichern
        // Ich denke hier steckt der Fehler, da ich ein 2d-Pointer initialisiere, der auf ein 2d Array zeigt -> Murks kommt raus
        // Wüsste aber sonst nicht,wie ich mit mein 2d-Array sonst einbinden kann
    char** pMap = createMap();

        // Map visualisieren
    for (int y = 0; y < 10; y++)
    {
        for (int x = 0; x < 10; x++)
        {
            cout << pMap[y][x];
        }

        cout << endl;
    }
}


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
char** createMap()
{
    // Länge und Breite Variablen deklarieren
    int nWidth, nHeight;

    // Pointer initialisieren
    int* pArr = nullptr;
    // Pointer das Array der inputNum() Funktion übergeben
    pArr = inputNum();

    // Den variablen die Werte des Arrays zuordnen
    nWidth = pArr[0];
    nHeight = pArr[1];

    // dynamischen Speicher wieder freigeben
    delete[] pArr;

    // Ausgabe der Variablen
    cout << "Width: " << nWidth << " , Height: " << nHeight << endl;

    // --------------------------------------------------------------

    // Dynamisches 2d-Array erzeugen
    char** const pMap = new char*[nHeight];

    for (int y = 0; y < nHeight; y++)
    {
        for (int x = 0; x < nWidth; x++)
        {
            // Array von Pointern neues Array für die Breite zuweisen
            pMap[y] = new char[x];
            // Jede "Koordinate" 'X' zuweisen um MAP visualisieren zu können
            pMap[y][x] = 'X';
            // MAP ausgeben
            cout << pMap[y][x];
        }
        cout << endl;
    }

    // 2d-Array zurückgeben
    return pMap;



}


int* inputNum()
{
    // Neuen Pointer initialisieren
    int* input = nullptr;
    // Dynamisches 1d-Array erzeugen und dem Pointer zuweisen
    input = new int[2];
    // Array mit Inputs befüllen
    cout << "Which width the Map should have?";
    cin >> input[0]; 
    cout << endl;
    cout << "Which height the Map should have?";
    cin >> input[1];
    cout << endl;
    // Array über Pointer der Funktion zurückgeben
    return input;
}


Ich versuche hier zu Testzwecken die Map sowohl in der Funktion, als auch ausserhalb der Funktion darzustellen. In der Funktion klappt das problemlos, doch in main() zeigt die Konsole folgendes an:

=========X
=========X
=========X
=========X
=========X
=========X
=========X
=========X
=========X
=========X

Wäre für eine Fehleranalyse sehr dankbar, bzw. wenn mir jemand evtl. erklären könnte, wie genau ich mein auf dem Heap abgelegtes Array am besten funktionsübergreifend aufrufen kann. In den ganzen Beispielen im Buch und Internet konnte ich bis jetzt nur Beispiele innerhalb einer Funktion finden =/

mfg

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

17.12.2015, 14:13

Ich empfehle std::array<std::array<char, 10>, 10>. Dieses Raw-Array-Geschubse da ist grundlos anfällig für dutzende Fehler. Mach ein typedef aus meinem Vorschlag und schon ist alles prima. Bei dynamischen Größen ginge auch vector<vector<char>>.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

cFx

Frischling

  • »cFx« ist der Autor dieses Themas
  • Private Nachricht senden

3

17.12.2015, 16:16

"Ich empfehle std::array<std::array<char, 10>, 10>. Dieses Raw-Array-Geschubse da ist grundlos anfällig für dutzende Fehler. Mach ein typedef aus meinem Vorschlag und schon ist alles prima. Bei dynamischen Größen ginge auch vector<vector<char>>."

Diese Lösungsansätze hatte ich auch gefunden, nur möchte ich mich bei diesem ersten "klein"-Projekt möglichst auf das konzentrieren, was ich bis dato gelernt habe und das irgendwie umsetzen (so gut es geht ... bis alles erstmal "funktioniert"), um die Basics zu festigen. Trotzdem danke dir, vll. hab ich mich da etwas ungünstig ausgedrückt.

Zeile 31 pMap[y] = new char[x];

Danke dir, dann schau ich da mal intensiver nach. Ich glaub ich hab das Problem auch gerade entdeckt =P

Das 10x10 Array habe ich für Testzwecke erstmal so eingegrenzt, um die Map-Anzeige hinzukriegen, wollte mich im Anschluss darum kümmern.

Lösung:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
for (int y = 0; y < nHeight; y++)
    {
        pMap[y] = new char[nWidth];
        for (int x = 0; x < nWidth; x++)
        {
            // Array von Pointern neues Array für die Breite zuweisen
            // Jede "Koordinate" 'X' zuweisen um MAP visualisieren zu können
            pMap[y][x] = 'X';
            // MAP ausgeben
            cout << pMap[y][x];
        }
        cout << endl;
    }


Hatte befürchtet, dass ich etwas mit den ganzen Pointern doch noch falsch verstanden habe und der Fehler dadruch verursacht wurde^^ Aber manchmal ist es echt viel Einfacher als man denkt =P Danke dir nochmal

xardias

Community-Fossil

Beiträge: 2 731

Wohnort: Santa Clara, CA

Beruf: Software Engineer

  • Private Nachricht senden

4

17.12.2015, 20:50

Ein kleiner tipp bezueglich inputnum: Du verwendest ein dynamisches array um mehrere Werte zurueck zu geben. Es gibt hier einige gute Alternativen die weniger Fehleranfaellig und wesentlich simpler sind:

C-/C++-Quelltext

1
2
3
4
5
6
7
int arr[2];
inputNum(arr);
...
void inputNum(int* arr) {
cin >> arr[0];
...
}


oder noch viel einfacher:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
int width, height;
inputNum(&width, &height);
...
void inputNum(int* width, int* height) {
cin >> *width;
cin >> *height;
...
}


Alternativ kannst du auch Referenzen verwenden, oder std::tuple<int, int> zurueck geben.

5

18.12.2015, 09:34

Alternativ kannst du auch Referenzen verwenden, oder std::tuple<int, int> zurueck geben.

Ein std::tuple ließe sich bei Bedarf dann auch in die entsprechenden Variablen entpacken:

std::tie(nWidth, nHeight) = inputNum();

cFx

Frischling

  • »cFx« ist der Autor dieses Themas
  • Private Nachricht senden

6

19.12.2015, 11:39

Danke euch, werde ich mir dann nochmal genauer anschauen. Mit den ganzen std:: ... - Möglichkeiten hab ich mich noch nicht wirklich auseinander gesetzt. Bin wie gesagt erstmal dran die Basics zu vertiefen =)

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

7

19.12.2015, 12:20

Die Standardbibliothek wirst du ja schon benutzen. Für Ein- und Ausgabe zum Beispiel. Das ist auch nichts wovor du Angst haben musst. Im Prinzip ist es eine riesige Sammlung von sinnvollen Klassen die dir viel Arbeit abnehmen und dir das Leben vereinfachen. Möglicherweise ist ja jetzt mal ein Zeitpunkt wo du da genauer rein schauen kannst. Als Beispiel kannst du dir ja mal std::vector ansehen. Das ist eine Klasse die du später sehr häufig verwenden wirst. Im Prinzip handelt es sich um ein dynamisches Array dessen Größe auch nachträglich weiter angepasst werden kann.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

cFx

Frischling

  • »cFx« ist der Autor dieses Themas
  • Private Nachricht senden

8

20.12.2015, 11:23

Jepp, setze mich gerade mit der STL auseinander =) Möchte mich nur nicht bei jedem "Problem" an eine library wenden, das erschwert den Weg die Dinge richtig zu verstehen ... Der Weg des geringsten Widerstandes und so =D

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

9

20.12.2015, 12:03

Die STL ist keine Library in dem Sinn, sie ist Teil von C++. Sie macht C++ erst zu dem, was es ist. Sie ist genauso Teil der Sprache, wie es ein Array oder eine Klasse ist. Sie nicht zu nutzen wäre fatal. Willst Du C++ verstehen und beherrschen, musst Du mit der STL umgehen können.
Davon mal abgesehen ist es besser sich mit einem Problem an eine Library zu wenden. Diese sind meist wesentlich besser getestet als das, was Du selbst schreibst. Alles selbst machen zu wollen ist ein typischer Anfänger-Fehler. Libraries zu verwenden ist guter Stil. Es gibt auch mit Libraries noch genug Code, den Du selbst schreiben musst.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

10

20.12.2015, 14:03

Vor allem würde Niemand ohne sehr guten Grund in C++ 2D Arrays über so Pointergedöns lösen wie du es hier machst. Alleine aufgrund der Fehleranfälligkeit und dem Problem dass man sich um Speicherfreigabe selbst kümmern muss.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige