dynamische Verwaltung-warum gehts nicht?
-
HI Leute,
ich bin mir jetzt nicht sicher, ob das das richtige Forum ist, aber bei Ansi C stand KEIN C++....
Also, mein Prob:
Ich habe eine Klasse Mp3 mit ein paar CString membern und ein paar Funktionen
Dann habe ich eine Klasse Mp3Manager, der mit CfileFind Verzeichnisse ausliest und die dann in einem dynamischen Array vom typ Mp3 speichern soll.Nur das will irgendwie nicht.
ich habe im Mp3Manager eine Member:
Mp3 *m_pMp3; UINT m_puiMp3Counter;
Im Konstruktor mache ich:
m_pMp3=(Mp3*)malloc(100*sizeof(Mp3));
Und in den Funktionen versuche ich:
//hier mir CFileFind ne Schleife //wenn ein Mp3 gefunden wurde m_pMp3Counter++; m_pMp3[m_pMp3Counter].SetName(...);
danach in der schleife schau ich noch ob der platz in dem array zu klein ist, und alokier dann mit realloc neuen.
Aber in der Zeile mit SetName kommt ein Access Violation an 0xc0000005 oder sowas. Da steht dann bei Debug: bei THIS:
m_name={""} und dann ich glaub bei m_pchdata "Wert kann nicht ausgewertet werden.Versteht ihr das?
Ich komm da so langsam nicht mehr mitgreetz, feiadragon
-
Wenn du dynamisch den Speicher reservieren willst und das in C++, dann nimm new und delete. Aber in deinem Fall würde sich ein vector oder evtl auch eine list aus der STL anbieten. Dann brauchst du dich auch nicht darum zu kümmern ob du Speicher nachholen musst oder nicht.
-
also wie:
m_pMp3 = new mp3[counter] oder wie soll das dann gehen?
und bei den anderen sachen muss ich erstmal schauen was das überhaupt ist
-
zum effizienteren Debuggen kannst du ja alles in einen Vector stecken, und per at () den Zugriff prüfen.
Außerdem versteh ich nicht, warum du in jedem Schleifendurchgang die Größe checkst und dann per realloc neu beschaffst. Schaff doch gleich genug an. Falls das aus irgendeinem Grund bei dir nicht gehen sollte => Vector.push_back.
-
nein, ich hab das bisher so gemacht, das der in jeder schleife guggt ob der counter%100 ==0 ist, und dann hat der halt 100 neue plätze allokiert.
Könnt ihr mir da vielleicht ein kleines Beispiel für schreiben? Klingt ganz gut, aber... naja mal schauen
-
feiadragon schrieb:
nein, ich hab das bisher so gemacht, das der in jeder schleife guggt ob der counter%100 ==0 ist, und dann hat der halt 100 neue plätze allokiert.
Und warum das? Das scheint mir etwas überflüssig. Warum kennst du erst in der Schleife die größe des Arrays?
also wenn du ne Hilfe zur benutzung von Vector brauchst musst du bei google vorbeischauen. Im Wesentlichen:
Vector<MP3> MP3Vector; //... for (...) { MP3Vector.at (Index); //geprüft, verhindert Indexüberschreitung MP3Vector.push_back (xyz); }
-
feiadragon schrieb:
Könnt ihr mir da vielleicht ein kleines Beispiel für schreiben? Klingt ganz gut, aber... naja mal schauen
beispiel für vector oder was ?
typedef vector<Mp3*> VectorMp3s; VectorMp3s vmp3s; vmp3s.push_back(new Mp3(...)); // fügt in den vector ein neues mp3 object hinzu
ansonsten wär die docu zu STL zu empfählen
-
feiadragon schrieb:
Ich habe eine Klasse Mp3 mit ein paar CString membern und ein paar Funktionen
Dann habe ich eine Klasse Mp3Manager, der mit CfileFind Verzeichnisse ausliest und die dann in einem dynamischen Array vom typ Mp3 speichern soll.Nur das will irgendwie nicht.
Das wundert mich nicht.
ich habe im Mp3Manager eine Member:
Mp3 *m_pMp3; UINT m_puiMp3Counter;
Im Konstruktor mache ich:
m_pMp3=(Mp3*)malloc(100*sizeof(Mp3));
malloc allokiert dir hier Speicher für 100 Mp3-Objekte. malloc ruft aber keine Konstruktoren auf. Du hast jetzt zwar Speicher viel Speicher, aber noch *kein einziges* Mp3-Objekt. Nicht drei, nicht zwei, nicht eins. Keins.
Und in den Funktionen versuche ich:
//hier mir CFileFind ne Schleife //wenn ein Mp3 gefunden wurde m_pMp3Counter++; m_pMp3[m_pMp3Counter].SetName(...);
Bumm! Hier greifst du auf ein Mp3-Objekt zu (SetName). Wie wir aber mittlerweile wissen, hast du aber bisher kein Mp3-Objekt.
Wahrscheinlich referenzierst du in SetName einen der CString. Da die aber noch gar nicht exitsieren -> gute Nacht.danach in der schleife schau ich noch ob der platz in dem array zu klein ist, und alokier dann mit realloc neuen.
Oha. Jetzt wird's kriminell. Spätestens hier haust du dir alles kurz und klein. realloc und Objekte mit nicht-trivialer-Kopiersemantik (z.B. CString) sind zwei völlig inkompatible Geschichten. Wenn realloc einen neuen Puffer anlegen muss, kopiert es den Inhalt des alten durch ein simples memcpy. Von Copy-Konstruktoren hat realloc noch nie was gehört und ruft sie deshalb auch nicht auf.
Aber in der Zeile mit SetName kommt ein Access Violation an 0xc0000005 oder sowas. Da steht dann bei Debug: bei THIS:
m_name={""} und dann ich glaub bei m_pchdata "Wert kann nicht ausgewertet werden.Versteht ihr das?
Ja. Und du jetzt hoffentlich auch.
Kurz: malloc und seine Freunde passen nicht in die Welt der Objekte. Wenn du mit malloc&Co arbeiten willst, musst du auf die Verwendung von Objekten à la CString verzichten. Dann darfst du nur C-kompatible Strukturen einsetzen (PODs).
-
gut danke, das werd ich mal ausprobieren...
Also: warum ich in der Schleife überprüfe:
in dieser schleife werden alle mp3s aus einem verzeichniss eingelesen, und ich weiß doch nicht ob das 10 oder 2000 sind, deswegen muss ich das jedesmal checken.
-
@HummeSikkins:
danke! jetzt hab ichs auch verstanden!