2010-10-27 18 views
5

Ho provato a convertire un progetto vc7.1 in vs2010 che ho ottenuto da codeproject. (Ed ecco il link h tt p: //www.codeproject.com/KB/cpp/transactions.aspx? Fid = 11253 & df = 90 & mpp = 50 & rumore = 3 & sorta = Posizione & view = Expanded & fr = 1 # xx0xxIl nuovo posizionamento chiama il costruttore se il puntatore passato è nullo?

Ma dopo convertito e modificato la sua configurazione.

trovo Debug senza successo, si dice un'eccezione non gestita in 0x0028e7b9 in DrawIt.exe: 0xC0000005: posizione di scrittura della violazione di accesso 0x00000000.

La linea di errore va come questo

data = new(Mm::Allocate(sizeof(DocData), sid)) DocData(); 

E la funzione

void* Allocate(size_t size, SPACEID sid) 
{ 
    AUDIT 

    Spaces::iterator s = spaces.find(sid); 
    if (s == spaces.end()) 
     return NULL; 

    Space& space = s->second; 
    if (!space.transacting) 
     return NULL; 

    size = max(size, sizeof(Free)); 

    // TODO: assert that "data" is allocated in space 
    space.AssertData(); 

    // are there any more free chunks? 
    if (!space.data->sFreeHead) { 
     space.data->Insert(space.More(size)); 
    } 

    AUDIT 

    // find the first chunk at least the size requested 
    Free* prev = 0; 
    Free* f = space.data->sFreeHead; 
    while (f && (f->size < size)) { 
     prev = f; 
     f = f->next; 
    } 

    AUDIT 
    // if we found one, disconnect it 
    if (f) { 
     space.data->locTree.remove((size_t)f); 

     if (prev) prev->next = f->next; 
     else space.data->sFreeHead = f->next; 

     f->next = 0; 
     memset(&f->loc, 0, sizeof(f->loc)); 
    } else { 
     f = space.More(size); 
    } 

    // f is disconnected from the free list at this point 

    AUDIT 

    // if the free chunk is too(?) big, carve a peice off and return 
    // the rest to the free list 
    if (f->size > (2*(size + sizeof(Free)))) { 
     Free* tmp = space.data->Slice(f, size); // slice size byte off 'f' 
     space.data->Insert(f); // return the remainder to the free list 
     f = tmp; 
    } 

    AUDIT 

    CHECK_POINTER(f) 

    void* p = reinterpret_cast<void*>((char*)f + sizeof(Free::SIZE_TYPE)); 

    CHECK_POINTER(p) 

    return p; 
} 

Chiunque ha ottenuto idea, plz?

Dato che non sono bravo in C++, ci vorrà un po 'di tempo prima di capire come risolvere questo problema. Appena caricato il codice sorgente source file, sarebbe gradito se qualcuno potesse aiutare.

+0

Questa è una bella domanda che può essere ribadito in termini più brevi come: * Fa nuova collocazione chiamare il costruttore se il puntatore passato è nullo * –

risposta

2

Bene, la funzione Allocate restituisce chiaramente NULL. È piuttosto difficile per noi dire dove e perché, ed è banale per te impostare i punti di interruzione e inoltrare autonomamente l'allocatore, quindi ti suggerisco di farlo e scoprire dove viene restituita la funzione.

+0

Esso restituisce un certo puntatore ... Dopo void * p = reinterpret_cast (? (char *) f + sizeof (Free :: SIZE_TYPE)); – WhiteTopaz

4

[Questa risposta potrebbe essere errata; vedere i commenti per la discussione; Lascerò questo non eliminato per il momento in modo da poter capire quale sia la risposta]

Allocate restituisce NULL in diversi casi di errore.

Non si controlla il risultato della chiamata Allocate prima di utilizzarlo.

È necessario controllare il risultato. In alternativa, è possibile generare un'eccezione quando si verifica un errore.

+0

Grazie, vedrò se posso ripararlo. – WhiteTopaz

+0

Ma P non è Nullo quando ritorna, restituisce 0x0042ffd8? – WhiteTopaz

+0

Hai davvero bisogno di verificare la presenza di null prima di chiamare il nuovo posizionamento? Non sono stato in grado di determinare questo dallo standard. Da un lato, sembra ragionevole fare, dall'altro, chiamare il no throw new implica che l'allocatore può restituire 0, e la successiva costruzione del posizionamento deve essere saltata ... Ho l'impressione che il posizionamento nuovo * può * essere chiamato su un puntatore nullo, ma nessun riferimento chiaro dallo standard. Potrebbe anche essere gestito da 'new (std :: nothrow)' eseguendo il controllo * prima * chiamando il nuovo posizionamento. BTW, g ++ 4.2.1: 'new (0) test;' non chiama il costruttore, né muore. –

Problemi correlati