dsound - csound wird im heap erstellt und ist bei laufzeit nicht mehr verfügbar
-
also die headline beschreibt mein prob schon ganz gut. ein zeiger auf ein feld mit zeigern auf csound's wird eben mit csounds gefüllt. in der methode csound::IsPlaying() (und komischerweise gerade da) stürzt das programm beim fünften sound ab... aber hier erst mal die quelltexte:
die sound.h
# include <dsound.h> # include "dsutil.h" /* * Implementierung der Sounds */ class sounds { private: CSoundManager smgr; CSound **snd; //Zeiger auf ein (Feld von) Zeiger(n) auf Sound(s) bool on; char **soundfiles; //Zeiger auf ein |Feld von Zeigern auf chars (Zeiger auf ein Feld von Strings) // | public: // | sounds(char *soundfile[]);//Arg. ist ein |Feld von Zeigern auf chars (Zeiger auf ein Feld von Strings) ~sounds(); int init(HWND wnd); void play(int snr); void toggleOnOff() {on = !on;} bool isOn() {return on;} };die zugehörige sound.cpp hier ist auch die funkion zu finden, in der das progg abstürzt. die liste an sounds ist in der main-fkt zu finden (siehe unten) da wird sie (lt. konstruktor) an das sound-obj. übergeben
#include "Sounds.h" sounds::sounds(char *soundfile[]) { soundfiles = new char*[]; soundfiles = soundfile; snd = new[8] CSound*; for(int i = 0; i < sizeof(soundfiles); i++) snd[i] = 0; on = 1; } sounds::~sounds() { for(int i = 0; i < sizeof(soundfiles); i++) if(snd[i]) delete snd[i]; } int sounds::init(HWND wnd) { HRESULT ret; if(!snd) return -1; ret = smgr.Initialize(wnd, DSSCL_PRIORITY, 2, 2205, 16); if(ret < 0) return ret; for(int i = 0; i < sizeof(soundfiles); i++) { ret = smgr.Create(snd+i, soundfiles[i]); if(ret < 0) return ret; } return S_OK; } void sounds::play(int snr) { if( !on) return; if(snd[snr]->IsSoundPlaying()) //bei dieser funktion stürzt das prog { snd[snr]->Stop(); snd[snr]->Reset(); } snd[snr]->Play(0,0); }und bei folgender zeile meldet debugger den fehler:
codefragment von biblioth.-fkt dsutil.cppBOOL CSound::IsSoundPlaying() { BOOL bIsPlaying = FALSE; if( m_apDSBuffer == NULL ) //hier erkennt es beim 5.sound den buffer nicht return FALSE;und zum comp. wer will die main. einfach entsprechende sounds durch irgendeine wav ersetzen und den teil mit den .bmp auskommentieren
# include <windows.h> # include "resource.h" # include "Sounds.h" # include "Display.h" const int ultris_nettobreite = 360; // Breite des Inneren des Haupfensters const int ultris_nettohoehe = 520; // Hoehe des Inneren des Hauptfensters int ultris_bruttobreite; // Breite des gesamten Haupfensters (incl. Rahmen) int ultris_bruttohoehe; // Hoehe des gesamten Haupfensters (incl. Rahmen) //Zugriffskonstanten für die Sounddateien enum SOUNDS { sound_start = 0, //Sound für neues Spiel sound_dreh = 1, //Sound bei Drehung sound_move = 2, //Sound bei rechts/links Bewegung sound_down = 3, //Sound bei Aufprall sound_row1 = 4, //Sound bei Abraeumen einer Reihe sound_row2 = 5, //Sound bei Abraeumen mehrerer Reihen sound_ende = 6, //Sound bei Spielende sound_win = 7, //Sound bei Eintrag in Highscore-Tabelle anzahl_sounds = 8 //Anzahl Sounds }; //Array mit Pfaden zu Sounddateien char *soundfiles[anzahl_sounds] = { "ul_start.wav", "ul_dreh.wav", "ul_move.wav", "ul_down.wav", "ul_row1.wav", "ul_row2.wav", "ul_ende.wav", "ul_win.wav" }; HINSTANCE ultris_instance; // Instanz der Ultris Applikation HWND ultris_window; // Das Hauptfenster von Ultris HMENU ultris_menu; // Das Menu von Ultris sounds ultris_sounds(soundfiles); // Der Player von Ultris display ultris_display; // Das Display von Ultris /* ** ultris_windowhandler */ LRESULT CALLBACK ultris_windowhandler( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_COMMAND: switch( LOWORD( wParam)) { case IDM_ENDE: PostMessage( hWnd, WM_CLOSE, 0, 0); return 0; case IDM_SOUND: ultris_sounds.toggleOnOff(); CheckMenuItem(ultris_menu, IDM_SOUND, ultris_sounds.isOn() ? MF_CHECKED : MF_UNCHECKED); return 0; case IDM_TEST: static int testno = 0; ultris_sounds.play(testno % 5); testno++; return 0; } break; case WM_GETMINMAXINFO: ((MINMAXINFO *)lParam)->ptMinTrackSize.x = ((MINMAXINFO *)lParam)->ptMaxTrackSize.x = ultris_bruttobreite; ((MINMAXINFO *)lParam)->ptMinTrackSize.y = ((MINMAXINFO *)lParam)->ptMaxTrackSize.y = ultris_bruttohoehe; return 0; case WM_MOVE: ultris_display.update(); return 0; case WM_PAINT: int i; ultris_display.hintergrund(); ultris_display.abdeckung(); for(i = 0; i < 6; i++) ultris_display.ziffer(i, i); for(i = 0; i < 10; i++) { ultris_display.feldstein(19-i, i); ultris_display.fallstein(1, i, 2*i); } for(i = 0; i < 4; i++) { ultris_display.prevstein(3, 0, i, 4, 1); } ultris_display.present(ultris_nettobreite, ultris_nettohoehe); break; case WM_DESTROY: PostQuitMessage( 0); return 0; } return DefWindowProc(hWnd, msg, wParam, lParam); } /* ** WinMain */ int APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int nCmdShow) { MSG msg; HACCEL acc; WNDCLASSEX wcx; HRESULT hr; ultris_instance = hInst; wcx.cbSize = sizeof( wcx); wcx.lpszClassName = TEXT( "Ultris"); wcx.lpfnWndProc = ultris_windowhandler; wcx.style = CS_VREDRAW | CS_HREDRAW; wcx.hInstance = ultris_instance; wcx.hIcon = LoadIcon( ultris_instance, MAKEINTRESOURCE( IDI_MAIN)); wcx.hIconSm = LoadIcon( ultris_instance, MAKEINTRESOURCE( IDI_MAIN)); wcx.hCursor = LoadCursor( NULL, IDC_ARROW); wcx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcx.lpszMenuName = MAKEINTRESOURCE( IDR_MENU); wcx.cbClsExtra = 0; wcx.cbWndExtra = 0; if( !RegisterClassEx( &wcx)) return 0; acc = LoadAccelerators( ultris_instance, MAKEINTRESOURCE(IDR_ACCEL)); ultris_bruttohoehe = ultris_nettohoehe + 2*GetSystemMetrics( SM_CYSIZEFRAME) + GetSystemMetrics( SM_CYMENU) + GetSystemMetrics( SM_CYCAPTION); ultris_bruttobreite = ultris_nettobreite + 2*GetSystemMetrics( SM_CXSIZEFRAME); ultris_window = CreateWindowEx( 0, TEXT( "Ultris"), TEXT( "Ultris"), WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, ultris_bruttobreite, ultris_bruttohoehe, NULL, NULL, ultris_instance, NULL); if( !ultris_window) return 0; ultris_menu = GetMenu( ultris_window); MoveWindow( ultris_window, (GetSystemMetrics(SM_CXSCREEN)-ultris_bruttobreite)/2, (GetSystemMetrics(SM_CYSCREEN)-ultris_bruttohoehe)/2, ultris_bruttobreite, ultris_bruttohoehe, TRUE); ShowWindow( ultris_window, nCmdShow); if(ultris_sounds.init(ultris_window) < 0) { MessageBox(ultris_window, "Fehler beim Initialisieren der Sounds", "Ultris-Fehlermeldung", MB_OK | MB_ICONERROR | MB_SETFOREGROUND); return 0; } CheckMenuItem(ultris_menu, IDM_SOUND, ultris_sounds.isOn() ? MF_CHECKED : MF_UNCHECKED); if(ultris_display.init(ultris_window, ultris_nettobreite, ultris_nettohoehe) < 0) { MessageBox(ultris_window, "Fehler beim Initialisieren der Grafik", "Ultris-Fehlermeldung", MB_OK | MB_ICONERROR | MB_SETFOREGROUND); return 0; } while( TRUE) { if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE)) { if( GetMessage( &msg, NULL, 0, 0 ) == 0) //Konsolenhinweis return 0; // Message ist WM_QUIT if( TranslateAccelerator( ultris_window, acc, &msg) == 0) { TranslateMessage( &msg); DispatchMessage( &msg); } } else { hr = ultris_display.cooperative(); if(hr < 0) { switch(hr) { case DDERR_EXCLUSIVEMODEALREADYSET: Sleep(10); break; case DDERR_WRONGMODE: ultris_display.free_all(); if(ultris_display.init(ultris_window, ultris_nettobreite, ultris_nettohoehe) < 0) { MessageBox(ultris_window, "Fehler beim Initialisieren der Grafik", "Ultris-Fehlermeldung", MB_OK | MB_ICONERROR | MB_SETFOREGROUND); return 0; } PostMessage(ultris_window, WM_PAINT, 0, 0); break; } } else { Sleep(1); //Hier Spielablauf } } } }also wer da die antwort
hat, warum beim aufruf des (gerade des 5. sounds) bei zugriff auf heap das programm abstürz, der ist für mich ein held. bei weiteren anfragen zum programm einfach anfragen. ersatzweise kann man zum ausführen ja die windows-sounds nehmen und umbenennen c:/windows/media...danke schon mal im voraus

DS
-
Dr$arez schrieb:
soundfiles = new char*[];
Das ist Unsinn. Du musst schon angeben, wieviele Elemente soundfiles haben soll.
soundfiles = soundfile;
Und selbst wenn das oben nicht Unsinn wäre, ist es das hier. Damit überschreibst du den Zeiger, den du eine Zeile vorher angefordert hast. Nettes Speicherleck.
for(int i = 0; i < sizeof(soundfiles); i++)
Lass dir doch mal ausgeben, was sizeof(soundfiles) ist. Und dann informier dich mal, was sizeof tut.
-
ach wie dumm.. ich hatte noch ein wenig am text rumgebastelt. also der konstruktor in der cpp ist natürlich falsch. richtig wäre (und dann trotzdem noch der fehler)
codefragment aus sounds.cpp:
sounds::sounds(char *soundfile[]) { soundfiles = soundfile; snd = new CSound*[sizeof(soundfile)]; for(int i = 0; i < sizeof(soundfiles); i++) snd[i] = 0; on = 1; }
-
Dr$arez schrieb:
also wer da die antwort
hat, warum beim aufruf des (gerade des 5. sounds) bei zugriff auf heap das programm abstürz, der ist für mich ein held.Dann fang shconmal an MFK als deinen Helden zu betrachten, denn er hat Dir die Antwort längst gesagt. Nochmal de Hinweis-> sizeof
-
bist gerne mein held.
aber die ganzen andeutungen bringen mir nichts. soweit ich weiß, kann man mit sizeof (neben der größe der basis-typen) auch die elementanzahl eines arrays herausbekommen und... ah, mir geht ein licht auf - aber ich denke erstemal weiter. mein gedanke war nämlich an 'soundfiles' ein array mit strings zu übergeben (zeiger auf liste von zeigern auf char's). das argument wäre dementsprechend ein pointer auf das 'string'-array. mit anhand diesem erstelle ich für 'snd' einen speicherbereich i.form eines arrays im heap und nehme richtigerweise die dimension für das array aus sizeof(argument). die information des argumentes (pointer auf array) selber speichere ich aber in soundfiles ab, einem zeiger auf zeiger auf char - was ja für uns das gleiche wie das argument ist (ptr. auf string-array) aber für den rechner dann kein array mehr darstellt. fälschlicherweise wende ich dann bei der initialisierung von snd die sizeof-methode auf 'soundfiles' an und bekomme dementsprechend nur die größe des pointers im speicher (4) zurück.
dann probier ich das jetzt mal aus.... und... funktioniert gar nichts. hab jetzt bei allen deklarationen den wert 8 (anzahl der sounds) reingeschrieben. jetzt kann er die sounds nicht initialisieren... ich glaube das muss ich jetzt nochmal in ruhe überdenkentrotzdem danke bis dahin mein held

DS
-
Nimm doch statt deinem Array einfach vector.
-
ich weiß nicht, aber ich glaube CSoundManager::Create(...) (aus DirectX) nimmt als erstes argument nur ein feld aus zeigern auf CSound's an
-
ich verzweifle. ich habe nun das feld für die sounds manuell dimensioniert. "snd = new CSound*[8]" und das im konstruktor. bei beenden stürzt das programm dann beim destruktor ab, weil es beim überprüfen von snd: "if(snd[i]) delete snd[i]" angeblich wild im speicher rumsucht. kann es sein, dass snd gar nicht als array von zeigern auf CSound's existiert? der debugger zeigt leider auch nicht den inhalt während der laufzeit an...

-
ok... für interessierte HIER:
http://www.file-upload.net/download-221247/V01.rar.html
gibt es .rar incl cpp-sourcecode und allen nötigen .rc und dateien. beim compilieren dürfte der fehler auftreten, wenn man den 5. sound abspielt. ich habe die ausgangssituation so gelassen, wie sie war (bzgl. sizeof). die sounds werden mit 'STRG + T' angespielt
also ich wäre echt baff, wenn jmd. die fehlerhafte(n) zeile(n) findet
-
Dr$arez schrieb:
aber die ganzen andeutungen bringen mir nichts.
Ich habe gesagt, du sollst dir ausgeben lassen, was sizeof(soundfiles) bzw. sizeof(soundfile) ist. Das war keine Andeutung. Deutlicher geht's nun wohl kaum.
soweit ich weiß, kann man mit sizeof (neben der größe der basis-typen) auch die elementanzahl eines arrays herausbekommen
Soweit du weißt, soso. Warum probierst du's nicht einfach aus, oder noch besser, liest nach?
Dr$arez schrieb:
ich verzweifle. ich habe nun das feld für die sounds manuell dimensioniert. "snd = new CSound*[8]" und das im konstruktor. bei beenden stürzt das programm dann beim destruktor ab, weil es beim überprüfen von snd: "if(snd[i]) delete snd[i]" angeblich wild im speicher rumsucht.
Hast du wirklich überall sizeof entfernt? Das steht viermal im Code.
Dr$arez schrieb:
ich weiß nicht, aber ich glaube CSoundManager::Create(...) (aus DirectX) nimmt als erstes argument nur ein feld aus zeigern auf CSound's an
Geht trotzdem mit vector. Übergib einfach die Adresse des ersten Elements.
also ich wäre echt baff, wenn jmd. die fehlerhafte(n) zeile(n) findet
Sounds.cpp, Zeilen 8, 9, 17, 34.
Sounds.cpp, Zeile 18 ist überflüssig, aber nicht falsch.
-
danke, hab den fehler gefunden... (abgesehen von sizeof) hat die fünfte sounddatei nicht den gesuchten namen gehabt
