Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

DarioFrodo

Treue Seele

  • »DarioFrodo« ist der Autor dieses Themas

Beiträge: 349

Wohnort: Kerkau, 100km nördlich von Magdeburg

Beruf: Selbstständig

  • Private Nachricht senden

1

24.11.2006, 16:17

Zeiger, new Probleme mit tbList

Ich habe eine String Klasse geschrieben, mit einem char Zeiger (char* m_pcZeichen) der im Konstruktor Speicher reserviert bekommt über new und im Deskonstruktor Speicher wieder freigibt:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
DString::~DString()
{
    //Freigeben

    if(m_pcString)
    {
        delete[] m_pcString;
        m_iNumChars = 0;
        m_pcString = NULL;
    }
}


Wenn ich jetzt in einer Funktion eine "DString* strTemp;" als Variable erstelle, den String des Paramters übergebe: (Kopier Operator)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    DString& operator = (const char* &pcStr)
    {
        int iNC = GetNumChars(pcStr);
        if(CheckMem(iNC))
        {
            Log.WriteToLog("DString::operator = Fehler beim ReAlloc von Speicher!");
            return *this;
        }
        //memcpy(m_pcString, pcStr, iNC*sizeof(char));

        strcpy(m_pcString, pcStr);
        m_iNumChars = iNC;
        return *this;

    }

und dann einen Zeiger auf strTemp der nächsten Funktion übergebe, welches den Inhalt (von m_pcString) kopiert in eine Struktur:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct sEntry
{
     DString str;
     int       iZahl;
};
tbList<sEntry> m_EntryList;

        //Neuen Eintrag erstellen

        sEntry* pNewEntry = new sEntry;
[Edit]
        pNewEntry->str = strTemp->GetString();
[/Edit]
        m_EntryList.AddEntry(pNewEntry);
        m_pAktuellEntry = m_EntryList.GetLastEntry();
                delete pNewEntry;


Wenn ich jetzt in der Funktion, die die andere aufgerufen hat zurückkehre und dann delete strTemp aufrufe kommt ne Fehlermeldung (BLOCK_TYPE_IS_VALID). Wenn ich das delete nicht aufrufe funktioniert es, aber dan habe ich doch ein Speicherleck, oder?

Könnt ihr mir da weiterhelfen?
Erst wenn der letzte Fluss vergiftet,
der letzte Baum gefällt,
der letzte Fisch gefangen,
dann werdet ihr merken, dass man Geld nicht essen kann

Man verkauft die Erde nicht, auf der die Menschen wandeln.

- Indianerweisheiten

Ich bin auch ein einhornimmond ;)

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

2

24.11.2006, 16:28

Was genau ist strName und wie genau ist GetString() aufgebaut?

C-/C++-Quelltext

1
pNewEntry->strName = strTemp->GetString(); 


// hast du auch einen Copyconstruktor in deiner Klasse? (nur ne Nebenbei-Frage)

DarioFrodo

Treue Seele

  • »DarioFrodo« ist der Autor dieses Themas

Beiträge: 349

Wohnort: Kerkau, 100km nördlich von Magdeburg

Beruf: Selbstständig

  • Private Nachricht senden

3

24.11.2006, 16:43

Konstruktoren:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
DString::DString(int iNumChars)
{
    //initen

    if(AllocMem(iNumChars)) Log.WriteToLog("DString::DString(int iNumChars) Es konnte kein Speicher reserviert werden!");
}

//-------------------------------------------------------------------------------------


DString::DString()
{
    if(AllocMem(2)) Log.WriteToLog("DString::DString() Es konnte kein Speicher reserviert werden!");
}

//-----------------------------------------------------------------------------------------------


DString::DString(char* pcString)
{
    if(AllocMem(GetNumChars(pcString)))
    {
        Log.WriteToLog("DString::DString(char* pcString) Es konnte kein Speicher reserviert werden!");
        return;
    }

    strcpy(m_pcString, pcString);
}

//--------------------------------------------------------------------------------------------------


DString::DString(DFile* pOpenFile)
{
    //Pointer prüfen

    if(!pOpenFile) return;
    //Ist die Datei offen?

    if(!pOpenFile->isOpen()) return;
    int iTemp = 0;
    //Größe einlesen

    if(pOpenFile->read(&iTemp, sizeof(int))) return;
    AllocMem(iTemp);
    //Zeichen einlesen

    if(pOpenFile->read(m_pcString, sizeof(char)*iTemp)) return;
}


Und GetString liefert einfach den Zeiger m_pcString zurück.

C-/C++-Quelltext

1
2
//Liefert einen Char Zeiger auf den String

    char* GetString() {return m_pcString;}
Erst wenn der letzte Fluss vergiftet,
der letzte Baum gefällt,
der letzte Fisch gefangen,
dann werdet ihr merken, dass man Geld nicht essen kann

Man verkauft die Erde nicht, auf der die Menschen wandeln.

- Indianerweisheiten

Ich bin auch ein einhornimmond ;)

DarioFrodo

Treue Seele

  • »DarioFrodo« ist der Autor dieses Themas

Beiträge: 349

Wohnort: Kerkau, 100km nördlich von Magdeburg

Beruf: Selbstständig

  • Private Nachricht senden

4

24.11.2006, 16:44

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
UDReturn DProfiler::Start(char* pcString)
{
    UDReturn result;
    DString* ptemp = new DString(pcString);
    result = Start(ptemp);
//  delete ptemp;

    return result;
}

//Nutzung

UDReturn DProfiler::Start(DString* pstrKlassName)
{
//  return UD_OK;

    Log.WriteToLog("DProfiler::Start");
    //Stop aufrufen um eventuell laufende Messungen zu beenden

    Stop();

    Log.WriteToLog("Nach Stop");
    if(!GetEntry(pstrKlassName))
    {
        //Neuen Eintrag erstellen

        sEntry* pNewEntry = new sEntry;
        pNewEntry->strName = pstrKlassName->GetString();
        m_EntryList.AddEntry(pNewEntry);
        m_pAktuellEntry = m_EntryList.GetLastEntry();
        UD_SAVE_DELETE(pNewEntry);
    //  delete pNewEntry;

        Log.WriteToLog("Neuer Eintrag erstellt!");
    }

    QueryPerformanceCounter((LARGE_INTEGER*)&m_llStartCount);
    m_llStart = m_llStartCount;

    Log.WriteToLog("Start End!");

    return UD_OK;
}
Erst wenn der letzte Fluss vergiftet,
der letzte Baum gefällt,
der letzte Fisch gefangen,
dann werdet ihr merken, dass man Geld nicht essen kann

Man verkauft die Erde nicht, auf der die Menschen wandeln.

- Indianerweisheiten

Ich bin auch ein einhornimmond ;)

DarioFrodo

Treue Seele

  • »DarioFrodo« ist der Autor dieses Themas

Beiträge: 349

Wohnort: Kerkau, 100km nördlich von Magdeburg

Beruf: Selbstständig

  • Private Nachricht senden

5

24.11.2006, 17:06

"Was genau ist strName und wie genau ist GetString() aufgebaut? "

strName ist eine DString Variable in einer Struktur (kein Pointer).

GetString() liefert den m_pcString(char* m_pcString)) der DString Variable zurück.
Erst wenn der letzte Fluss vergiftet,
der letzte Baum gefällt,
der letzte Fisch gefangen,
dann werdet ihr merken, dass man Geld nicht essen kann

Man verkauft die Erde nicht, auf der die Menschen wandeln.

- Indianerweisheiten

Ich bin auch ein einhornimmond ;)

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

6

24.11.2006, 17:27

Komisch... schonmal im Debugger getestet, ob innerhalb von Start Änderungen an pTemp vorgenommen werden? Also Überwachung hinzufügen und dann Einzelschritt -> eine Veränderung sollte dann rot markiert werden.

Tritt der Fehler beim delete im Destruktoraufruf (also letztendlich beim inneren delete) auf oder vor / nach dem Destruktoraufruf?

DarioFrodo

Treue Seele

  • »DarioFrodo« ist der Autor dieses Themas

Beiträge: 349

Wohnort: Kerkau, 100km nördlich von Magdeburg

Beruf: Selbstständig

  • Private Nachricht senden

7

24.11.2006, 17:48

Debuggen, gibt es da irgendeinen Trick?
Ich habe "Visual C++6 2005 Express Edition" und zwischen jedem Schritt (selbst wenn nur eine Variable eine Zahl zugewiesen bekommt wie iZahl = 1) vergehen Sekunden, ehe die Maus wieder reagiert. Das bringt einen zum Verzweifeln.

Der Debugger zeigt nach dem Absturz immer auf folgende Stelle aus dem Deskonstruktor von DString:

C-/C++-Quelltext

1
delete[] m_pcString;


Wenn ich die delete in der DProfiler::Start() aufrufe (oder UD_SAVE_DELETE) dann kommt der gleiche Fehler.
Erst wenn der letzte Fluss vergiftet,
der letzte Baum gefällt,
der letzte Fisch gefangen,
dann werdet ihr merken, dass man Geld nicht essen kann

Man verkauft die Erde nicht, auf der die Menschen wandeln.

- Indianerweisheiten

Ich bin auch ein einhornimmond ;)

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

8

24.11.2006, 19:51

Ist AllocMem(iNumChars) deine eigene Funktion, wie arbeitet sie?

Es muss entweder irgendwo ein Sicherheitslag geben (also dass eine Addresse vom Stack in deine Variable gelangt oder so) oder du allokierst den Speicher nicht mit new... delete funktioniert nur für mit new allokierten Speicher.

DarioFrodo

Treue Seele

  • »DarioFrodo« ist der Autor dieses Themas

Beiträge: 349

Wohnort: Kerkau, 100km nördlich von Magdeburg

Beruf: Selbstständig

  • Private Nachricht senden

9

24.11.2006, 19:55

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//Init

bool DString::AllocMem(int iNumChars)
{
    //Speicher reservieren

    m_pcString = new char[GetNextPotenz(iNumChars)];
//  m_iNumChars = GetNextPotenz(iNumChars);

    m_iNumChars = iNumChars;

    //Speicher nullen

    memset(m_pcString, (int)'\0', GetMemSize());

    if(NULL == m_pcString) return true;

    return false;
}

//********************
Erst wenn der letzte Fluss vergiftet,
der letzte Baum gefällt,
der letzte Fisch gefangen,
dann werdet ihr merken, dass man Geld nicht essen kann

Man verkauft die Erde nicht, auf der die Menschen wandeln.

- Indianerweisheiten

Ich bin auch ein einhornimmond ;)

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

10

24.11.2006, 21:39

Sry, aber langsam steh ich echt auf dem Schlauch, was das Problem angeht :(

Ich frag mich aber auch, was du mit der DString-Klasse eigentlich erreichen willst, dass du ständig haufenweise Funktionen aufrufst

z.B. new char[GetNextPotenz(iNumChars)];
wozu brauch man bitte ne Funktion, wenn man schon die Anzahl der chars hat??

Also entweder hat noch jemand anders ne gute Idee oder du müsstest mir mal den gesamten Code schicken / hochladen - is einfach nich effektiv, wenn immer in einer Funktion wieder ne Folgefunktion kommt die ich nich kenne.

// bitte nich einfach hier mit Codetags rein - das is bei großen Mengen ne Qual zu lesen^^

Werbeanzeige