Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » dynamisches 2d-Array

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: [ 1 ] [ 2 ] > 3 < [ 4 ]
020
13.09.2011, 06:59 Uhr
~leiti7
Gast


So danke. das haut jetzt mal hin. aber mein nächstes problem liegt beim freimachen der arrays.
mein programm stürzt dauernd ab dabei.
Kann mir vll jemand sagen wo mein fehler liegt?

so habe ichs versucht:


C++:

void arraydel (void)
{
    for(int i = 0; i < zeilenanz; ++i)
    {
        delete[] m[i];

        delete[] p[i];

        delete[] q[i];

        delete[] l[i];

        delete[] n[i];

        delete[] druck[i];

        delete[] deltadruck[i];

        delete[] werte[i];

        delete[] xwerte[i];

        delete[] ywerte[i];

        delete[] einzelfl[i];

        delete[] druckmw[i];

        delete[] einzelkraft[i];
    }
    delete[] m;

    delete[] p;

    delete[] q;

    delete[] l;

    delete[] n;

    delete[] druck;

    delete[] deltadruck;

    delete[] werte;

    delete[] xwerte;

    delete[] ywerte;

    delete[] einzelfl;

    delete[] druckmw;

    delete[] einzelkraft;
}


 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
021
13.09.2011, 08:33 Uhr
ao

(Operator)


Der Code ist OK, es sei denn, zeilenAnz hat zwischendurch mal seinen Wert geändert und ist größer geworden als es zu dem Zeitpunkt war, als du die ganzen new-Aufrufe gemacht hast. Dann würdest du nämlich mehr Arrays freigeben als du geholt hast.

Wenn du das ausschließen kannst, liegts vermutlich daran, dass dein Programm doch noch irgendwo Speicherinhalte kaputtschreibt und dabei die Datenstrukturen erwischt, die die Speicherverwaltung (das Teil, was du mit new und delete aufrufst) angelegt hat. Man MUSS mit Arrays äußerst sorgfältig sein, dass man nirgendwo über die Grenzen läuft.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
022
13.09.2011, 08:51 Uhr
~leiti7
Gast


oke... dass sich zeilenz ändert kann ich ausschließen.
gibt es eine einfache und schnelle möglichkeit um herauszufinden wo und wann ich Speicherinhalte kaputtschreibe oder muss ich das komplette programm nochmal genau durchleuchten und durchdenken?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
023
13.09.2011, 09:35 Uhr
~leiti7
Gast


wenn ich dann bei der Fehlermeldung auf retry klicke hüpft das programm auf folgende zeilen:


C++:
#ifdef _MT

_CRTIMP void __cdecl _free_dbg(
        void * pUserData,
        int nBlockUse
        )
{
        /* lock the heap
         */

        _mlock(_HEAP_LOCK);

        /* allocate the block
         */

        _free_dbg_lk(pUserData, nBlockUse);

        /* unlock the heap
         */

        _munlock(_HEAP_LOCK);
}

void __cdecl _free_dbg_lk(

#else  /* _MT */

_CRTIMP void __cdecl _free_dbg(

#endif  /* _MT */

        void * pUserData,
        int nBlockUse
        )
{
        _CrtMemBlockHeader * pHead;

        /* verify heap before freeing */
        if (_crtDbgFlag & _CRTDBG_CHECK_ALWAYS_DF)
            _ASSERTE(_CrtCheckMemory());

        if (pUserData == NULL)
            return;

        /* forced failure */
        if (!(*_pfnAllocHook)(_HOOK_FREE, pUserData, 0, nBlockUse, 0L, NULL, 0))
        {
            _RPT0(_CRT_WARN, "Client hook free failure.\n");

            return;
        }

        /*
         * If this ASSERT fails, a bad pointer has been passed in. It may be
         * totally bogus, or it may have been allocated from another heap.
         * The pointer MUST come from the 'local' heap.
         */

        _ASSERTE(_CrtIsValidHeapPointer(pUserData));

        /* get a pointer to memory block header */
        pHead = pHdr(pUserData);

        /* verify block type */
        _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));

        /* if we didn't already check entire heap, at least check this object */
        if (!(_crtDbgFlag & _CRTDBG_CHECK_ALWAYS_DF))
        {
            /* check no-mans-land gaps */
            if (!CheckBytes(pHead->gap, _bNoMansLandFill, nNoMansLandSize))
                _RPT3(_CRT_ERROR, "DAMAGE: before %hs block (#%d) at 0x%08X.\n",
                    szBlockUseName[_BLOCK_TYPE(pHead->nBlockUse)],
                    pHead->lRequest,
                    (BYTE *) pbData(pHead));

            if (!CheckBytes(pbData(pHead) + pHead->nDataSize, _bNoMansLandFill, nNoMansLandSize))
                _RPT3(_CRT_ERROR, "DAMAGE: after %hs block (#%d) at 0x%08X.\n",
                    szBlockUseName[_BLOCK_TYPE(pHead->nBlockUse)],
                    pHead->lRequest,
>>>>>                   (BYTE *) pbData(pHead));
        }

        if (pHead->nBlockUse == _IGNORE_BLOCK)
        {
            _ASSERTE(pHead->nLine == IGNORE_LINE && pHead->lRequest == IGNORE_REQ);
            /* fill the entire block including header with dead-land-fill */
            memset(pHead, _bDeadLandFill,
                sizeof(_CrtMemBlockHeader) + pHead->nDataSize + nNoMansLandSize);
            _free_base(pHead);
            return;
        }

        /* CRT blocks can be freed as NORMAL blocks */
        if (pHead->nBlockUse == _CRT_BLOCK && nBlockUse == _NORMAL_BLOCK)
            nBlockUse = _CRT_BLOCK;

        /* Error if freeing incorrect memory type */
        _ASSERTE(pHead->nBlockUse == nBlockUse);

        /* keep track of total amount of memory allocated */
        _lCurAlloc -= pHead->nDataSize;

        /* optionally reclaim memory */
        if (!(_crtDbgFlag & _CRTDBG_DELAY_FREE_MEM_DF))
        {
            /* remove from the linked list */
            if (pHead->pBlockHeaderNext)
            {
                pHead->pBlockHeaderNext->pBlockHeaderPrev = pHead->pBlockHeaderPrev;
            }
            else
            {
                _ASSERTE(_pLastBlock == pHead);
                _pLastBlock = pHead->pBlockHeaderPrev;
            }

            if (pHead->pBlockHeaderPrev)
            {
                pHead->pBlockHeaderPrev->pBlockHeaderNext = pHead->pBlockHeaderNext;
            }
            else
            {
                _ASSERTE(_pFirstBlock == pHead);
                _pFirstBlock = pHead->pBlockHeaderNext;
            }

            /* fill the entire block including header with dead-land-fill */
            memset(pHead, _bDeadLandFill,
                sizeof(_CrtMemBlockHeader) + pHead->nDataSize + nNoMansLandSize);
            _free_base(pHead);
        }
        else
        {
            pHead->nBlockUse = _FREE_BLOCK;

            /* keep memory around as dead space */
            memset(pbData(pHead), _bDeadLandFill, pHead->nDataSize);
        }
}



genauer gesagt auf die zeile mit den >>>>> davor. ich weis nicht ob das euch was sagt. mir sagt es jedenfalls nichts ^^
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
024
13.09.2011, 12:34 Uhr
ao

(Operator)


Hmhm. Sowas ähnliches hab ich mir gedacht. Das ist die Routine, die einen Speicherblock freigibt.

Die Speicherverwaltung legt beim Aufruf von new um den Block herum ein paar Bytes "Niemandsland" an und füllt diese mit einem bestimmten Muster. Beim delete erwartet sie, dieses Muster wieder vorzufinden, andernfalls hat jemand im Speicher herumgepfuscht. Genau das sagt die Fehlermeldung.

Der Fehler wird hier nur aufgedeckt. Entstanden ist er ganz woanders. Wie findet man sowas?

Stell fest, welches Array das ist, das beim Freigeben den Fehler anzeigt. Entstanden ist der Fehler wahrscheinlich beim Schreiben auf dieses Array (genauer: über dessen Grenzen hinaus) oder auf eins der beiden im Speicher angrenzenden Arrays.

Wie findet man die angrenzenden Arrays?

Wenn dein Programm eine Stelle hat, wo es all seinen Speicher holt, und die new-Operationen nicht übers ganze Programm verteilt sind, dann hast du eine gute Chance, dass diese drei Kandidaten aufeinanderfolgend geholt wurden und deshalb benachbart stehen. Die Reihenfolge der new-Aufrufe im Code entspricht dann wahrscheinlich (sicher ist das leider nicht) der Reihenfolge im Speicher. Du kannst das verifizieren, indem du Debug-Ausgaben im Code unterbringst und die Arrays mit Namen und Adressen auflisten lässt.

Du musst also nach Programmierfehlern suchen beim Zugriff auf diese drei Arrays. Wenn du dabei nichts findest, hast du noch zwei Möglichkeiten:

1. Das ganze Programm absuchen. Kann sehr lange dauern, besonders dann, wenn du zu Blindheit für eigene Fehler neigst und außerdem nicht weißt, wonach du eigentlich suchst.

2. Das Programm neu schreiben. Das ist nicht so blöd wie es klingt. Bei der Gelegenheit könntest du auch die ganzen Oldstyle-Arrays rausschmeißen und stattdessen std::vector oder einen ähnlichen Container verwenden. Würde deinem Programm möglicherweise gut tun.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
025
13.09.2011, 14:48 Uhr
~leiti7
Gast


Danke für die Hilfe, jetz klappts
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
026
13.09.2011, 15:17 Uhr
ao

(Operator)


Und was isses gewesen? Vielleicht kann man ja noch was daraus lernen.
Dieser Post wurde am 13.09.2011 um 15:17 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
027
14.09.2011, 06:45 Uhr
~leiti7
Gast


Es war so wie du vermutet hast....
habe bei einem array über die Grenzen hinaus geschrieben.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
028
14.09.2011, 07:28 Uhr
~leiti7
Gast


Hätte da noch ne frage:
gibt es eine einfache variante wie man alle Beistriche eines Dokuments, das in mein Programm eingelesen wird, in Punkte umwandelt? so, dass das c-programm die kommazahlen auch wirklich als kommazahlen erkennt.

mfg
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
029
14.09.2011, 07:54 Uhr
~leiti7
Gast


sry meinte natürlich c++ programm nicht c-programm
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: [ 1 ] [ 2 ] > 3 < [ 4 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: