C++ Array dynamisch anlegen

Gast #784743
Ich hab in C++ folgendes Problem.
Ich habe eine Klasse z.B. CBaum. Nun möchte ich in dieser Klasse ein 
Array dynamisch erstellen. Zuvor habe ich die gewünschte Array Größe 
(array_size_w und array_size_h) während der Programmlaufzeit ermittelt.
Wie kann man in C++ nun in einer Klasse ein Array mit der Größe 
array_size_w*array_size_h anlegen?

classe CBaum
{
int array_size_w;
int array_size_h;
BYTE *daten;

CBaum();
}

//Konstruktor
CBaum::CBaum()
{
daten=new BYTE[array_size_w*array_size_h];
}

//Beispiel Hauptprogramm
void main(void)
{
CBaum baum_obj;
baum_obj.daten[1]=55;
}
Gast
Bin kein C++ler, aber so vielleicht:

//Konstruktor
CBaum::CBaum(int w, int h)
{
array_size_w = w;
array_size_h = h;
daten=new BYTE[array_size_w*array_size_h];
}

//Beispiel Hauptprogramm
void main(void)
{
CBaum baum_obj(111, 222); /* Oder was auch immer */
baum_obj.daten[1]=55;
}
Gast
> Wie kann man in C++ nun in einer Klasse ein Array mit der Größe
> array_size_w*array_size_h anlegen?

So wie man es an jeder anderen Stelle auch macht. Mit new. Da du das 
schon tust, verstehe ich die Frage nicht. Dein Programm hat aber noch 
einige andere Fehler, die ich unten mal kommentiert habe.
Noch was anderes: Wenn du das Array dynamisch erzeugst, mußt du es auch 
wieder freigeben, denn sonst hast du ein Speicherleck.

> classe CBaum

Du meintest sicherlich:
1
class CBaum

Was ist eigentlich ein C-Baum?

> {
> int array_size_w;
> int array_size_h;
> BYTE *daten;
>
> CBaum();

Diese Member sind allesamt privat, also wirst du nie darauf zugreifen 
können.

> }

Hier fehlt ein Semikolon.

> //Konstruktor
> CBaum::CBaum()
> {
> daten=new BYTE[array_size_w*array_size_h];
> }

array_size_w und array_size_h haben hier noch undefinerte Werte. 
Außerdem sollte man Membervariablen in der Initialisierungsliste mit 
Werten belegen, also eher so:
1
CBaum::CBaum()
2
    : daten(new BYTE[array_size_w*array_size_h])
3
{
4
}

> void main(void)

main muß immer int zurückgeben.
Gast
> Wenn ich es so mache dann erscheint folgende Fehlermeldung

Was ist denn "so"? Dein Code von oben wird so gar nicht erst durch den 
Compiler gehen. Also mußt du wohl irgendwelchen anderen Code probiert 
haben. Poste doch diesen bitte mal. Und bitte keinen für das Posting neu 
eingetippten Code mit einem Dutzend anderen Fehlern, dafür ohne den 
Fehler, um den es eigentlich geht, sondern den Originalcode, den du 
durch den Compiler geschickt hast.
Gast
1
class Chisto
2
{
3
public:
4
  int array_size_w;
5
  int array_size_h;
6
  BYTE *bildgrau;
7

8
  Chisto(int w, int h);
9

10
};
11

12
// Konstruktor
13
Chisto::Chisto(int w, int h)
14
{
15
  array_size_w = w;
16
  array_size_h = h;
17
  bildgrau[array_size_w*array_size_h];
18
}
19

20
// Hauptprogramm
21
void main (void)
22
{
23
...
24
Chisto histo_obj(infoheader.biWidth,infoheader.biHeight);
25
...
26
histo_obj.bildgrau[j*infoheader.biHeight+i] = gray;
27
}
Gast
> Das verstehe ich nicht:
>
> CBaum::CBaum()
>     : daten(new BYTE[array_size_w*array_size_h])
> {
> }
>
>
> ist da nicht ein Fehler?

Nein (außer ich hab was übersehen).
Membervariablen werden in der Initialisierungsliste initialisiert, und 
die sieht eben so aus. Für einfache Datentypen wie int und Zeiger spielt 
es keine große Rolle, ob du sie initialisierst oder ihnen stattdessen im 
Konstruktorkörper einen Wert zuweist. Wenn du aber auch Konstanten, 
Referenzen oder Instanzen von Klassen als Member hast, macht es einen 
Unterschied. Am besten gewöhnt man sich gleich eine ordentliche 
Initialisierung an.


> Chisto::Chisto(int w, int h)
> {
>   array_size_w = w;
>   array_size_h = h;
>   bildgrau[array_size_w*array_size_h];

Wo ist denn das new hin? Die obige Zeile tut so wie sie da steht gar 
nichts.

> }
Gast
1
class Chisto
2
{
3
public:
4
  int array_size_w;
5
  int array_size_h;
6
  BYTE *bildgrau;
7

8
  Chisto();
9

10
};
11

12
// Konstruktor
13
Chisto::Chisto()
14
   :bildgrau(new BYTE[array_size_w*array_size_h])
15
{
16
}
17

18
// Hauptprogramm
19
void main (void)
20
{
21
...
22
Chisto histo_obj(infoheader.biWidth,infoheader.biHeight);
23
histo_obj.array_size_w = infoheader.biWidth; 
24
histo_obj.array_size_h = infoheader.biHeight;
25
...
26
histo_obj.bildgrau[2] = gray;
27
...

Fehlermeldung: nicht genügend Speicher platz!
Gast
sorry hab da nich ein Fehler im Programm gesehen.

Jetzt erscheint die Fehlermeldung: Nicht genügend Speicherplatz 
vorhanden!
1
class Chisto
2
{
3
public:
4
  int array_size_w;
5
  int array_size_h;
6
  BYTE *bildgrau;
7

8
  Chisto();
9

10
};
11

12
// Konstruktor
13
Chisto::Chisto()
14
   :bildgrau(new BYTE[array_size_w*array_size_h])
15
{
16
}
17

18
// Hauptprogramm
19
void main (void)
20
{
21
...
22
Chisto histo_obj;
23
histo_obj.array_size_w = infoheader.biWidth; 
24
histo_obj.array_size_h = infoheader.biHeight;
25
...
26
histo_obj.bildgrau[2] = gray;
27
...
Gast
Du mußt array_size_w und array_size_h schon auch initialisieren. Deine 
Zuweisung aus main kommt ja erst nach dem Konstruktor, der diese Werte 
schon braucht. Svens Antwort kombiniert mit der Initialisierungsliste:
1
//Konstruktor
2
CBaum::CBaum(int w, int h)
3
    : array_size_w(w),
4
      array_size_h(h),
5
      daten(new BYTE[array_size_w*array_size_h])
6
{
7
}

Dann in main:
1
Chisto histo_obj(infoheader.biWidth, infoheader.biHeigt);
Erstmal: Wo ist das delete[]?
Zweitens: Warum nimmst du nicht direkt std::vector<BYTE> und sparst dir 
das ganze new/delete-Gewurschtel? Wenn du vector nicht kennst, tipp 
bitte "vector C++" in google ein bevor du hier danach fragst.

Ausserdem:
Du hast ja immer noch void main(void) da stehen, obwohl das oben schon 
mal kritisiert wurde? Wenn du Hilfe kommentarlos ignorierst, verlieren 
hier viele Leute schnell die Lust dir weiter zu antworten.


btw: Das Praefix "C" vor einer Klasse stammt uebrigens aus grauer 
Vorzeit, und genau genommen sogar aus einem Missverstaendnis: Die MFC 
(von Microsoft) hat C als Praefix fuer Klassen benutzt, damit die 
Klassen der User nicht mit den Klassen der MFC kollidieren. Die Idee 
war, dass die Klassen der MFC "C" als Praefix haben und die Klassen der 
User eben gerade kein Praefix. Ein manueller namespace, sozusagen.
Wenn nun aber normale Programmierer ihre Klassen mit demselben Praefix 
versehen wie die MFC, untergraebt das den urspruenglichen Sinn des 
Praefixes voellig. In modernem C++ nimmt man daher einen namespace und 
kein Praefix.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.