(Visual C ++) Memoria di allocazione dinamica non un puntatore valido dopo l'eliminazione del puntatore

StackOverflow https://stackoverflow.com/questions/8834906

Domanda

Ho un programma, quando faccio clic sul pulsante "Download", Crea un nuovo thread per scaricare le pagine Web e archivialo in un'allocazione dinamica char* variabile.

Ma ora faccio clic su "Download", il programma mostra le seguenti informazioni:

---------------------------
Microsoft Visual C++ Debug Library
---------------------------
Debug Assertion Failed!

Program: d:\dev\debug\test.exe
File: dbgheap.c
Line: 1279

Expression: _CrtIsValidHeapPointer(pUserData)

Sembra che il problema sia correlato all'allocazione del heap o al problema delle relazioni.

void SomeClass::get()
{
    buf = this->download(url);
    while (some condition)
    {
        ......
        ......
        bufContent = this->download(url);
        ......
        ......
        sql = new char[sqlSize];
        ZeroMemory(sql,sqlSize);
        sql_utf8 = new char[sqlSize*2];
        ZeroMemory(sql_utf8,sqlSize*2);
        ......
        ......
        delete[] bufContent;bufContent=NULL;
        delete[] sql;
        delete[] sql_utf8;
    }
    delete[] buf; buf=NULL;//debug run to here, get Assertion Failed error
}

download funzione :

char* SomeClass::download(TCHAR* url)
{
    char   * pBuf = NULL ;
    int    nBufLen = 0 ;
    TRY
    {
        // connection
        CInternetSession   sess ;
        sess.SetOption (INTERNET_OPTION_CONNECT_TIMEOUT, 30 * 1000) ;
        sess.SetOption (INTERNET_OPTION_CONNECT_BACKOFF, 1000) ;
        sess.SetOption (INTERNET_OPTION_CONNECT_RETRIES, 1) ;

        DWORD       dwFlag = INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_RELOAD ;
        CHttpFile   * pF = (CHttpFile*)sess.OpenURL(url, 1, dwFlag); ASSERT(pF);
        if (!pF)
        {AfxThrowInternetException(1);}

        // connection status
        CString      str ;
        pF->QueryInfo (HTTP_QUERY_STATUS_CODE, str) ;
        if (str != _T("200"))
        {
            pF->Close() ;
            delete pF ;
            AfxThrowInternetException(1);
        }
        // start QzoneBlog
        int nLen,nLenCopy;
        pF->QueryInfo (HTTP_QUERY_CONTENT_LENGTH, str) ; // file's length
        if (_ttoi(str))
        {
            // know file's size
            nLenCopy = nLen = (nBufLen = _ttoi(str)) ;
            char    * p = (pBuf = new char[nLen+8]) ;
            ZeroMemory (p, nLen+8) ;

            while (TRUE)
            {
                int   n = pF->Read (p, (nLen < 1024) ? nLen : 1024) ;
                if (n <= 0)
                    break ; // success exit
                p += n ; nLen -= n ;
            }

            // interrupted
            if (nLen != 0)
            {
                //delete[] pBuf; pBuf=NULL;
                nBufLen = 0 ;
            }
        }
        pF->Close() ;
        delete pF ;
        return pBuf;
    }
    CATCH_ALL(e) {
        return 0;
    }
    END_CATCH_ALL
}
È stato utile?

Soluzione

Le seguenti istruzioni:

    sql = new char[sqlSize];
    ZeroMemory(sql,sizeof(sql));

Allocare il numero di byte sqlsize, quindi cancella i primi quattro, poiché sizeof (sql) è 4. Quindi, se sqlsize è inferiore a 4, stai assegnando meno di 4 byte, e poi stai zero 4 byte memoria. Ciò di cui hai bisogno è:

    ZeroMemory(sql,sqlSize);

Inoltre: se _ttoi(str) fallisce, non allochi un buffer, ma lo restituisci e presumo che tu procedi per provare a liberarlo. Questa è probabilmente la causa l'eccezione del puntatore non valido.

Altri suggerimenti

Questo è il risultato del superamento della memoria. Hai scritto su un po 'di memoria che non è nella gamma allocata.

Qualcosa di simile a:

char *buf = new char[4];
buf[4]=23;    // actual error
delete[] buf; // runtime error (Debug Assertion Fail)

Probabilmente genererà tale errore.

Sarà difficile individuare in un grande programma, poiché l'asserzione di debug non si verifica quando si verifica l'errore effettivo. Suggerirei di usare alcuni strumenti come Verificatore dell'applicazione Per tenere un orologio in tua memoria, il programma è in esecuzione. Il verificatore dell'applicazione interromperà il programma ogni volta che c'è un errore di memoria.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top