integer Array als Rückgabewert einer Funktion
-
Ich wollte halt sowas machen:
Alles was nach return steht wird niemals aufgerufen, du könntest dir also diese beiden Zeilen genauso gut sparen ;). Du erzeugst ein Speicherleck.
Wenn du sagst du würdest davon abraten, wie würdest du es machen?
Gut du fragst nach meiner Variante: Ich würde einen std::vector<short> zurückgeben, genausogut könnte ich mir aber auch ein short[]-Array vorstellen das bereits übergeben wird (das war in C usus):
void foo (char* iarr, short* oarr, int len) { for(int i = 0; i < len; ++i) oarr[i] = do_something(iarr[i]); }Besser aber wahrscheinlich die Variante mit vector!
MfG SideWinder
-
Nach einem return wird die Funktion abgebrochen. Dein delete [] wird nie ausgeführt.
Wie man es sonst macht: Mit einer Klasse die den Speicher selber wieder aufräumt (spätestens im Dekonstruktor) oder (je nach dem was du machen willst) mit der STL.
-
Was willst du denn umrechnen;
size_t Filesize = 1000; size_t short_size = Filesize / sizeof(short int ); char * char_buffer = new char[Filesize]; short int * short_buffer = (short int *)char_buffer; for ( int i = 0; i < short_size; i++ ) { cout << short_buffer[i] << endl; } delete [] char_buffer;Kurt
-
Vielen Dank für eure Antworten. An dieser Stelle wäre ein Speicherleck richtig schlecht
(die Funktion wird vorraussichtlich ca 2000 mal pro Tag aufgerufen)Hab es jetzt geändert aber laufen tuts leider nicht.
bool CIhwfView::wavDataChunk_to_intArray(short* pData,CString Path, int offset) {... for (unsigned long i=1; i<=FileSize - offset;i++) { pData[i] = (short)(unsigned char)pBuffer[i];//hier UNHANDLED EXCEPTION! } ... } //Jetzt der Aufruf: ... short* DataChunk = new short [FileSize]; wavDataChunk_to_intArray(DataChunk, "\\test.wav", 43); ...Woher kommt die oben kommentierte Exception? muss ich pData auch noch mal = new short[FileSize] machen??
-
joa ich muss wohl new short[Filesize] machen,
Hab jetzt nur feststellen müssen, dass ich ja noch die Fileze bracuch, also hab ich an de Funktionskopf noch ein unsigned long* angehängt.bool CIhwfView::wavDataChunk_to_intArray(short* pData,CString Path, int offset, unsigned long* FileSize)sobald ich nun was machen will mit Filesize bekomm ich Probleme.
Schreib ich:FileSize = streamoff(FileBin.tellg());sagt er mir cannot convert from long to unsigned long*
schreib ich:*FileSize = streamoff(FileBin.tellg());Bringt er keinen Kompilerfehler, aber eine Exception.
Wieso geht das bei pData und bei dem jetzt nicht

Vielen Dank für all eure Hilfen!
-
Polofreak schrieb:
schreib ich:
*FileSize = streamoff(FileBin.tellg());Bringt er keinen Kompilerfehler, aber eine Exception.
Wieso geht das bei pData und bei dem jetzt nicht

Vielen Dank für all eure Hilfen!
Du hast nirgends Speicher für FileSize angefordert. Filesize hat einen zufälligen Inhalt. Wenn du mit *Filesize den pointer dereferenzierst schreibst du irgendwohin. Der Unterschied zu pData ist dass du pData mit new initialisiert hast.
Ich nehme einmal an dass du in der methode CIhwfView::wavDataChunk_to_intArray() FileSize als pointer deklariert hast da du Filesize im aufrufenden programm verwenden wilst. Ich würde Filesize als referenz deklarieren. etwa sobool CIhwfView::wavDataChunk_to_intArray(short* pData,CString Path, int offset, unsigned long & FileSize) {... FileSize = streamoff(FileBin.tellg()); for (unsigned long i=0; i< FileSize - offset;i++) { pData[i] = (short)(unsigned char)pBuffer[i]; } ... }der Aufruf würde dann so aussehen
unsigned long datasize = 0; if ( wavDataChunk_to_intArray(DataChunk, "\\test.wav", 43, datasize ) { for ( int i = 0; i < datasize - 43; i++ ) { .... } }BTW wie kommst du eigentlich darauf dass die samples in einer wav-datei bei offset 43 beginnen und am ende des files enden. Offset 43 könnte bei mono 8-bit stimmen muss aber nicht denn das wav-fileformat ist ein sogenanntes container format. in einer datei könnten auch mehrere sounds mit verschiedenen sample raten oder auflösungen liegen, ausserdem könnten die samples auch komprimiert sein. Diese informationen findest du im fmt-chunk.
vielleicht solltest du dir http://www.borg.com/~jglatt/tech/wave.htm ansehen da ist das wave format ganz gut beschrieben.
Kurt
-
die 43 hab ich jetzt mal als beispiel genommen, weil meine TestWave halt 8 Bit Mono ist. Wie das Format aufgebaut ist weiß ich mittlerweile.Das mit dem Filesize als Referenz war genau das was ich da haben wollte. aber mir ist aufgefallen dass ich pData doch nicht das richtige drin stehen habe (was ich eigentlich annahm). Mir ist auch klar warum aber ich weiß nicht was dagegen tun!
void CIhwfView::OnButton1() { UpdateData(true); short DataChunk; //hier sollte glaube ich ein new hin, aber mit welcher größe?? Die ist ja zu dem Zeitpunkt noch nicht bekannt. unsigned long FileSize =0; wavDataChunk_to_intArray(DataChunk, "\\test.wav", 43, FileSize); for (unsigned long i=0;i<=FileSize-44;i++) { m_sAusgabe.Format("%s%d an der Stelle %d\r\n",m_sAusgabe,DataChunk[i],i); //somit hab ich hier das von dir angesprochene Probel, dass ich irgendwo hin zeige! UpdateData(FALSE); } } bool CIhwfView::wavDataChunk_to_intArray(short & pData,CString Path, int offset, unsigned long & FileSize) { unsigned long dec=0; fstream FileBin(Path, ios::in|ios::out|ios::binary); if (FileBin.is_open()) { // 1. Dateigröße bestimmen. FileBin.seekg(0, ios::end); FileSize = streamoff(FileBin.tellg()); FileBin.seekg(0, ios::beg); // 2. Puffer anlegen und Datei einlesen. char* pBuffer = new char[FileSize]; FileBin.seekg(offset); FileBin.read(pBuffer, FileSize - offset); pData = new short[FileSize]; pData[0] = offset; for (unsigned long i=1; i<FileSize - offset;i++) { pData[i] = (short)(unsigned char)pBuffer[i]; } // Nachher wieder aufräumen. delete [] pBuffer; UpdateData(false); } else MessageBox("cannot open File!","ERROR"); return true; }
-
Du musst aus
bool CIhwfView::wavDataChunk_to_intArray(short & pData,CString Path, int offset, unsigned long & FileSize)bool CIhwfView::wavDataChunk_to_intArray(short * pData,CString Path, int offset, unsigned long & FileSize)machen. Man beachte das * anstatt dem & bei pData! Wenn du mit new Arbeitest bekommst du einen Pointer zurück. Aber! Du musst den den speicher den du da anforderst auch wieder freigeben (mit delete[])
mfg
( Edit-Wars: Bin etwas daneben )
-
Referenz ist wieder die Lösung
void CIhwfView::OnButton1() { UpdateData(true); short * DataChunk = 0; // speicher wird in wavDataChunk_to_intArray zugeordnet unsigned long FileSize =0; wavDataChunk_to_intArray(DataChunk, "\\test.wav", 43, FileSize); for (unsigned long i=0;i<=FileSize-44;i++) { m_sAusgabe.Format("%s%d an der Stelle %d\r\n",m_sAusgabe,DataChunk[i],i); UpdateData(FALSE); } delete [] DataChunk; // DataChunk wieder freigeben } bool CIhwfView::wavDataChunk_to_intArray(short *& pData,CString Path, int offset, unsigned long & FileSize) { unsigned long dec=0; fstream FileBin(Path, ios::in|ios::out|ios::binary); if (FileBin.is_open()) { // 1. Dateigröße bestimmen. FileBin.seekg(0, ios::end); FileSize = streamoff(FileBin.tellg()); FileBin.seekg(0, ios::beg); // 2. Puffer anlegen und Datei einlesen. char* pBuffer = new char[FileSize]; FileBin.seekg(offset); FileBin.read(pBuffer, FileSize - offset); pData = new short[FileSize]; pData[0] = offset; for (unsigned long i=1; i<FileSize - offset;i++) { pData[i] = (short)(unsigned char)pBuffer[i]; } // Nachher wieder aufräumen. delete [] pBuffer; UpdateData(false); } else MessageBox("cannot open File!","ERROR"); return true; }es ist natürlich unschön dass du in einer funktion den speicher anforderst und in einer anderen wieder freigibst.
am besten machst du DataChunk zur membervariable von CIhwfView und gibst den speicher im destruktor von CIhwfView wieder frei.
Kurt
-
ZuK respekt!
Hier läuft er allerdings nur einmal durch:
for (unsigned long i=0;i<=FileSize-44;i++) { m_sAusgabe.Format("%s%d an der Stelle %d\r\n",m_sAusgabe,DataChunk[i],i); UpdateData(FALSE); }sobald i=1
ASSERTGetBuffer(nMaxLen); VERIFY(_vstprintf(m_pchData, lpszFormat, argListSave) <= GetAllocLength());Weißt du auch hier weiter?
-
ALso mit CStrings kenn ich mich nicht wirklich aus. Du übergibst aber dem CString::Format eine referenz auf sich selbst. denke du willst eigentlich.
m_sAusgabe.Format("Sample ist %d an der Stelle %d\r\n",DataChunk[i],i);Kurt
Edit: jetzt habe ich es verstanden. du willst an m_sAusgabe immer etwas anhängen. Keine Ahnung wie das bei einem CString geht moglicherweise so.
CString tmp(m_sAusgabe); m_sAusgabe.Format("%s%d an der Stelle %d\r\n",tmp,DataChunk[i],i);
-
So ein Müll sonst ging das so!
Naja egal so klappt es jetzt:
CString tmp = ""; for (unsigned long i=0;i<=FileSize-44;i++) { m_sAusgabe.Format("%d an der Stelle %d\r\n",DataChunk[i],i); tmp += m_sAusgabe; }Vielen Lieben Dank, ohne euch hätte ich es nicht geschafft!