ThisZeiger lößt nur Fehler aus
-
hi,
bei folgendem Code wird bei JEDER Benutzung des this-Ptrs ein Speicherfehlgriff ausgelößt...könnt ihr mir vll sagen wieso ?
Achja, die Definition:
char *_pszEntryName;/* ============================================================ */ // GetEntryName: Ermittelt den Namen des Eintrag. // unsigned int CListEntry::GetEntryName(char *pszBuffer, unsigned int uiBufferSize) { if(pszBuffer == NULL || !uiBufferSize) // Länge ermitteln { if(this->_pszEntryName != NULL) return (strlen(this->_pszEntryName)); else return (0); } // Kopieren return (strlen(strncpy(pszBuffer, this->_pszEntryName, uiBufferSize))); }Danke!!
-
Das Bißchen Code reicht nicht für eine Diagnose. Zeig mal mehr. Konstruktor von CListEntry wäre interessant. Eventuell auch Copy-Konstruktor oder Zuweisungsoperator.
Nebenbei bemerkt: char * zu verwenden ist eine schlechte Idee. std::string ist dein Freund.
-
Evtl. benutzt du die Instanz als Zeiger, welcher aber nicht korrekt initialisiert wurde? Beim letzten return lässt sich auch nicht ausschliessen, dass this->_pszEntryName ein Nullzeiger ist.
-
danke schonmal, also hier noch mal der ganze Code (viel):
______________________________________________
Datei: ClassTypes.h#ifndef _CLASS_TYPES_H_ #define _CLASS_TYPES_H_ class CPlaylist; class CListEntry; typedef unsigned long EntryEnumType; typedef EntryEnumType* PEntryEnumType; typedef CListEntry* PCListEntry; typedef CListEntry** DPCListEntry; typedef const CListEntry* CPCListEntry; typedef struct tagENTRYDATA // ed, EntryData { unsigned long ulEntryType; void *pvMetaTagInfo; } ENTRYDATA, *PENTRYDATA; // Allgemeine Typenkategorien #define AUDIO_FILE_TYPE (0x00000040L) // Dateitypen #define MP3_AUDIO_FILE (0x00000080L) #define WAV_AUDIO_FILE (0x00000100L) // Maximale Anzahl an Listeneinträgen #define MAX_ENTRY_NUMBER (50000) // Flags für das Ermitteln/Löschen/Hinzufügen eines Eintrags #define OP_ENTRY_SPECIFIC_POS (0x000) #define OP_ENTRY_FIRST_ENTRY (0x001) #define OP_ENTRY_MIDDLE_ENTRY (0x002) #define OP_ENTRY_LAST_ENTRY (0x003) #endif /* _CLASS_TYPES_H_ */______________________________________________
Datei: CPlaylist.h#ifndef _C_PLAY_LIST_H_ #define _C_PLAY_LIST_H_ #include <ShlWApi.h> #include "ClassTypes.h" #include "CListEntry.h" #pragma comment(lib, "Shlwapi.lib") class CPlaylist { /* -------------------------------------------------------*/ private: /* -Declarations */ /* -------------------------------------------------------*/ EntryEnumType _etTotalEntries; DPCListEntry _pEntryPtrArray; /* -------------------------------------------------------*/ public: /* -Declarations */ /* -------------------------------------------------------*/ /* void */ CPlaylist (void); /* void */ ~CPlaylist (void); bool AddEntry (char* pszEntryName, char* pszSourcePath, PENTRYDATA pedData); bool DeleteEntry (void); PCListEntry GetEntryFromPos (EntryEnumType etPosition); PCListEntry GetEntryFromName (char* pszEntryName); PCListEntry GetEntryFromPath (char* pszSourcePath); PCListEntry GetFirstEntry (void); PCListEntry GetLastEntry (void); EntryEnumType GetEntryNumber (void); bool IsEmpty (void); }; #endif /* _C_PLAY_LIST_H_ */______________________________________________
Datei: CPlaylist.cpp#include "CPlaylist.h" #pragma warning(disable: 4800) #pragma auto_inline(on) /* ============================================================ */ // Konstruktor: Führt Standard-Initialisierungen durch. // CPlaylist::CPlaylist(void) { this->_pEntryPtrArray = NULL; this->_etTotalEntries = 0; this->_pEntryPtrArray = new PCListEntry[MAX_ENTRY_NUMBER]; } /* ============================================================ */ // Destruktor: Baut die Klassen-Elemente wieder ab. // Gibt Speicher frei. // CPlaylist::~CPlaylist(void) { if(this->_etTotalEntries) { EntryEnumType etCount; for(etCount = 1; etCount <= this->_etTotalEntries; ++etCount) { delete (this->_pEntryPtrArray[etCount]); this->_pEntryPtrArray[etCount] = NULL; } } this->_pEntryPtrArray = NULL; this->_etTotalEntries = 0; } /* ============================================================ */ // AddEntry: Fügt ein neuen Eintrag ein. // bool CPlaylist::AddEntry(char* pszEntryName, char* pszSourcePath, PENTRYDATA pedData) { if(pszEntryName == NULL || pszSourcePath == NULL || pedData == NULL) return (false); this->_pEntryPtrArray[this->_etTotalEntries + 1] = new CListEntry(pszEntryName, pszSourcePath, pedData); if(this->_pEntryPtrArray[this->_etTotalEntries + 1] == NULL) return (false); this->_etTotalEntries += 1; return (true); } /* ============================================================ */ // DeleteEntry: Löscht den letzten Eintrag. // bool CPlaylist::DeleteEntry(void) { if(this->_etTotalEntries) { delete (this->_pEntryPtrArray[this->_etTotalEntries]); this->_pEntryPtrArray[this->_etTotalEntries] = NULL; this->_etTotalEntries -= 1; return (true); } return (false); } /* ============================================================ */ // GetEntryNumber: Ermittelt die aktuelle Anzahl der Einträge. // EntryEnumType CPlaylist::GetEntryNumber(void) { return (this->_etTotalEntries); } /* ============================================================ */ // IsEmpty: Prüft, ob die Liste leer ist. // bool CPlaylist::IsEmpty(void) { return (!(bool)this->_etTotalEntries); } /* ============================================================ */ // GetEntryFromPos: Holt einen Zeiger auf den über // etPosition (Positionsangabe) adressierten // Eintrag. // PCListEntry CPlaylist::GetEntryFromPos(EntryEnumType etPosition) { if(this->IsEmpty() || etPosition > this->_etTotalEntries || !etPosition) return (NULL); return (this->_pEntryPtrArray[etPosition]); } /* ============================================================ */ // GetEntryFromName: Holt einen Zeiger auf den über // pszEntryName (Eintragname) adressierten // Eintrag. // PCListEntry CPlaylist::GetEntryFromName(char* pszEntryName) { if(this->IsEmpty() || pszEntryName == NULL) return (NULL); char* pszBuffer; unsigned int uiBufferSize; int iResult; for(EntryEnumType etCount = 0; etCount < this->_etTotalEntries; etCount++) { if(this->_pEntryPtrArray[etCount] != NULL) { uiBufferSize = this->_pEntryPtrArray[etCount]->GetEntryName(NULL, 0); pszBuffer = new char[uiBufferSize + 1]; if(pszBuffer == NULL) return (NULL); else this->_pEntryPtrArray[etCount]->GetEntryName(pszBuffer, uiBufferSize + 1); iResult = StrCmpN(pszBuffer, pszEntryName, strlen(pszEntryName)); delete [] pszBuffer; if(!iResult) return (this->_pEntryPtrArray[etCount]); else continue; } } return (NULL); } /* ============================================================ */ // GetEntryFromPath: Holt einen Zeiger auf den über // pszSourcePath (Eintragquelle) adressierten // Eintrag. // PCListEntry CPlaylist::GetEntryFromPath(char* pszSourcePath) { if(this->IsEmpty() || pszSourcePath == NULL) return (NULL); char *pszBuffer; unsigned int uiBufferSize; int iResult; for(EntryEnumType etCount = 0; etCount < this->_etTotalEntries; etCount++) { if(this->_pEntryPtrArray[etCount] != NULL) { uiBufferSize = this->_pEntryPtrArray[etCount]->GetSourcePath(NULL, 0); pszBuffer = new char[uiBufferSize + 1]; if(pszBuffer == NULL) return (NULL); else this->_pEntryPtrArray[etCount]->GetSourcePath(pszBuffer, uiBufferSize + 1); iResult = StrCmpN(pszBuffer, pszSourcePath, strlen(pszSourcePath)); delete [] pszBuffer; if(!iResult) return (this->_pEntryPtrArray[etCount]); else continue; } } return (NULL); } /* ============================================================ */ // GetFirstEntry: Ermittelt einen Zeiger auf den // ersten Eintrag. // PCListEntry CPlaylist::GetFirstEntry(void) { if(this->IsEmpty()) return (NULL); return (this->_pEntryPtrArray[1]); } /* ============================================================ */ // GetLastEntry: Ermittelt einen Zeiger auf den // letzten Eintrag. // PCListEntry CPlaylist::GetLastEntry(void) { if(this->IsEmpty()) return (NULL); return (this->_pEntryPtrArray[this->_etTotalEntries]); } #pragma auto_inline(off) #pragma warning(default: 4800)______________________________________________
Datei: CListEntry.h#ifndef _C_LIST_ENTRY_H_ #define _C_LIST_ENTRY_H_ #include <IOStream> #include <Windows.h> #include <ShlWApi.h> #include "ClassTypes.h" #pragma comment(lib, "Shlwapi.lib") class CListEntry { /* -------------------------------------------------------*/ private: /* -Declarations */ /* -------------------------------------------------------*/ char* _pszEntryName; char* _pszSourcePath; ENTRYDATA _edEntryData; bool _fClassInitDone; /* -------------------------------------------------------*/ public: /* -Declarations */ /* -------------------------------------------------------*/ CListEntry (void); CListEntry (char *pszName, char *pszPath, PENTRYDATA pedData); ~CListEntry (void); /* inline */ bool SetEntryName (char *pszName); /* inline */ bool SetSourcePath (char *pszPath); /* inline */ bool SetEntryData (PENTRYDATA pedData); /* inline */ unsigned int GetEntryName (char *pszBuffer, unsigned int uiBufferSize); /* inline */ unsigned int GetSourcePath (char *pszBuffer, unsigned int uiBufferSize); /* inline */ PENTRYDATA GetEntryData (void); /* inline */ PCListEntry GetNextEntry (void); /* inline */ bool IsInitialized (void); /* inline */ bool IsLastEntry (void); friend class CPlaylist; }; #endif /* _C_LIST_ENTRY_H_ */______________________________________________
Datei: CListEntry.cpp#include "CListEntry.h" /* ============================================================ */ // Konstruktor: Führt Standard-Initialisierungen durch. // CListEntry::CListEntry(void) { this->_pszEntryName = NULL; this->_pszSourcePath = NULL; this->_fClassInitDone = false; } /* ============================================================ */ // Konstruktor: Standard-Initialisierungen jedoch mit Angabe // des Eintrag Namen und des Quellpfades. // CListEntry::CListEntry(char *pszName, char *pszPath, PENTRYDATA pedData) { this->_fClassInitDone = true; this->_pszEntryName = NULL; this->_pszSourcePath = NULL; if(pszName != NULL) { this->_pszEntryName = new char[strlen(pszName) + 1]; if(this->_pszEntryName == NULL) this->_fClassInitDone = false; else strcpy(this->_pszEntryName, pszName); } else this->_pszEntryName = NULL; if(pszPath != NULL) { this->_pszSourcePath = new char[strlen(pszPath) + 1]; if(this->_pszSourcePath == NULL) this->_fClassInitDone = false; else strcpy(this->_pszSourcePath, pszPath); } else this->_pszSourcePath = NULL; if(pedData != NULL) { if(!pedData->ulEntryType || pedData->pvMetaTagInfo == NULL) this->_fClassInitDone = false; else { this->_edEntryData.ulEntryType = pedData->ulEntryType; this->_edEntryData.pvMetaTagInfo = pedData->pvMetaTagInfo; } } else this->_fClassInitDone = false; } /* ============================================================ */ // Destruktor: Baut die Klassen-Elemente wieder ab. // Gibt Speicher frei. // CListEntry::~CListEntry(void) { delete [] this->_pszEntryName; delete [] this->_pszSourcePath; this->_pszEntryName = NULL; this->_pszSourcePath = NULL; this->_fClassInitDone = false; } /* ============================================================ */ // SetEntryName: Ändert den Eintrag Namen. // bool CListEntry::SetEntryName(char *pszName) { if(pszName == NULL) return (false); delete [] this->_pszEntryName; this->_pszEntryName = new char[strlen(pszName) + 1]; if(this->_pszEntryName == NULL) return (false); else strcpy(this->_pszEntryName, pszName); return (true); } /* ============================================================ */ // GetEntryName: Ermittelt den Namen des Eintrag. // unsigned int CListEntry::GetEntryName(char *pszBuffer, unsigned int uiBufferSize) { if(pszBuffer == NULL || !uiBufferSize) { if(this->_pszEntryName != NULL) // !!!!<<<== HIER TRITT DER FEHLER AUF ==>>>!!!! return (strlen(this->_pszEntryName)); else return (0); } return (strlen(strncpy(pszBuffer, this->_pszEntryName, uiBufferSize))); } /* ============================================================ */ // SetSourcePath: Ändert den Quellpfad zu diesem in der Liste // assoziierten Eintrag. // bool CListEntry::SetSourcePath(char *pszPath) { if(pszPath == NULL) return (false); delete [] this->_pszSourcePath; this->_pszSourcePath = new char[strlen(pszPath) + 1]; if(this->_pszSourcePath == NULL) return (false); else strcpy(this->_pszSourcePath, pszPath); return (true); } /* ============================================================ */ // GetSourcePath: Ermittelt den Quellpfad zu diesem in der // Liste assoziierten Eintrag. // unsigned int CListEntry::GetSourcePath(char *pszBuffer, unsigned int uiBufferSize) { if(pszBuffer == NULL || !uiBufferSize) return ((this->_pszSourcePath != NULL ? strlen(this->_pszEntryName) : 0)); return (strlen(strncpy(pszBuffer, this->_pszSourcePath, uiBufferSize))); } /* ============================================================ */ // IsInitialized: Prüft, ob die Klasse bereits initialisiert // wurde; also ob es sich um einen gültigen // Eintrag handelt. // bool CListEntry::IsInitialized(void) { return (this->_fClassInitDone); }_________________________________________________________________
So das ist alles was benötigt wird...
nochmals vielen Dank für eure Mühen, wär echt genial wenn wir das lösen könnten...hier noch die Main.cpp zum testen...(also Beispielcode):
Datei: Main.cpp:#include "Playlist\CListEntry.h" #include "Playlist\CPlaylist.h" int main() { static CPlaylist cPlaylist; static ENTRYDATA edData; char szBuffer[200]; PCListEntry pCEntry = NULL; cPlaylist.AddEntry("ACDC - Ride On", "C:\\acdc_ro", &edData); cPlaylist.AddEntry("ACDC - High Voltage", "C:\\acdc_hv", &edData); cPlaylist.AddEntry("ACDC - Who Made Who", "C:\\acdc_wmw", &edData); cPlaylist.AddEntry("ACDC - Heetseaker", "C:\\acdc_h", &edData); /***********************************************************************************/ /* Test 1.: GetEntryFromPos() => FEHLERFREI!!! */ pCEntry = cPlaylist.GetEntryFromPos(1); if(pCEntry != NULL) { pCEntry->GetEntryName(szBuffer, 200); std::cout << "Name des 1. Eintrags: " << szBuffer << std::endl << std::endl; } else std::cout << "Fehler beim Ermitteln des 1. Eintrags der Playlist." << std::endl; /***********************************************************************************/ /* Test 2.: GetEntryFromPos() => FEHLERFREI!!! */ pCEntry = cPlaylist.GetEntryFromPos(2); if(pCEntry != NULL) { pCEntry->GetEntryName(szBuffer, 200); std::cout << "Name des 2. Eintrags: " << szBuffer << std::endl << std::endl; } else std::cout << "Fehler beim Ermitteln des 2. Eintrags der Playlist." << std::endl; /***********************************************************************************/ /* Test 1.: GetEntryFromName() => FEHLER!!! */ pCEntry = cPlaylist.GetEntryFromName("ACDC - Ride On"); if(pCEntry != NULL) { pCEntry->GetSourcePath(szBuffer, 200); std::cout << "Der Quellpfad des Eintrags: 'ACDC - Ride On': " << szBuffer << std::endl << std::endl; } else std::cout << "Fehler: 'ACDC - Ride On' konnte in der Playlist nicht gefunden werden." << std::endl; return (0); }Die Fehlermeldung im DebugModus ist: _pszEntryName: Ausdruck kann nicht ausgewertet werden
... oha, wer das lößt kreigt n Küsschen

-
Beim ersten Durchschauen fällt mir mal das hier auf:
bool CPlaylist::AddEntry(char* pszEntryName, char* pszSourcePath, PENTRYDATA pedData) { if(pszEntryName == NULL || pszSourcePath == NULL || pedData == NULL) return (false); this->_pEntryPtrArray[this->_etTotalEntries + 1] = new CListEntry(pszEntryName, pszSourcePath, pedData); if(this->_pEntryPtrArray[this->_etTotalEntries + 1] == NULL) return (false); this->_etTotalEntries += 1; return (true); }Die belegst hier als erstes _pEntryPtrArray[1]. Das Array fängt aber bei [0] an. Und an anderer Stelle greifst du auch auf [0] zu, was zu undefiniertem Verhalten führen dürfte.
Davon mal abgesehen enthält dieser Quelltext Memory-Leaks, überflüssigen Code und stillistische Patzer in größeren Mengen. Vielleicht wäre es doch angeraten sich noch mal ein Bißchen mehr mit den Grundlagen zu beschäftigen ...
-
hi,
Davon mal abgesehen enthält dieser Quelltext Memory-Leaks, überflüssigen Code und stillistische Patzer in größeren Mengen. Vielleicht wäre es doch angeraten sich noch mal ein Bißchen mehr mit den Grundlagen zu beschäftigen ...
Memory-Leaks: Jo das stimmt, aber sonz dürften keine drinn sein...hab mir ehrlich gesagt nicht genug gedanken gemacht...
überflüssigen Code: wenn du auf meine typedef hinaus willst; die sind absicht...und auch wenn das von 'außen' uneinsichtig erscheint...mir gefällts

stillistische Patzer: weiß zwar nit was du meinst...hmm vll. die Verwendung von this an allen ecken und enden...das ist nicht nötig ich weiß, aber auch das ist mein Stil, und wenn man nun mal länger proggt, dann entwickelt man eben seinen Stil...mir gefällt das...und übersichtlich finde ich es auch

aber danke...das mit dem 0-Index werd ich noch mal überarbeiten *THUMBS UP*
tHX!