Forum: PC-Programmierung C++ Array dynamisch anlegen


von Petty (Gast)


Lesenswert?

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;
}

von Sven P. (Gast)


Lesenswert?

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;
}

von Rolf Magnus (Gast)


Lesenswert?

> 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.

von Petty (Gast)


Lesenswert?

Danke für die Hilfe. Wenn ich es so mache dann erscheint folgende 
Fehlermeldung:
Unbehandelte Ausnahme in Test.exe: 0xC0000005: Access Violation

von Rolf Magnus (Gast)


Lesenswert?

> 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.

von Petty (Gast)


Lesenswert?

Das verstehe ich nicht:
1
CBaum::CBaum()
2
    : daten(new BYTE[array_size_w*array_size_h])
3
{
4
}

ist da nicht ein Fehler?

von Petty (Gast)


Lesenswert?

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
}

von Rolf Magnus (Gast)


Lesenswert?

> 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.

> }

von Petty (Gast)


Lesenswert?

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!

von Petty (Gast)


Lesenswert?

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
...

von Rolf Magnus (Gast)


Lesenswert?

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);

von Simon K. (simon) Benutzerseite


Lesenswert?

Oh gott, wie wäre es denn mal mit einem C++ Buch?

von Christoph _. (chris)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.