Domanda

Per C ++ di sviluppo per sistemi a 32 bit (sia esso Linux, Mac OS o Finestre, PowerPC o x86) Ho inizializzato indicatori che altrimenti non definita (ad esempio non possono immediatamente ottenere un valore corretto) in questo modo:

int *pInt = reinterpret_cast<int *>(0xDEADBEEF);

(Per salvare la digitazione e di essere SECCO il lato destro normalmente essere in una costante, ad esempio BAD_PTR.)

Se pInt è dereferenziato prima che faccia un valore appropriato allora va in crash immediatamente sulla maggior parte dei sistemi (al posto di crash molto più tardi, quando un po 'di memoria viene sovrascritto o andare in un lunghissimo ciclo).

Naturalmente il comportamento dipende dalla sottostante hardware (ottenere un numero intero a 4 byte dal dispari affrontare 0xDEADBEEF da un processo utente può essere perfettamente valido), ma il crash è stata affidabile al 100% per tutto il sistemi ho sviluppato finora per (Mac OS 68xxx , Mac OS PowerPC, Linux Redhat Pentium, GUI di Windows Pentium, Windows console Pentium). Per esempio su PowerPC è illegale (bus guasto) per recuperare un numero intero 4 byte da un indirizzo dispari.

Che cosa è un buon valore per questo su sistemi a 64 bit?

È stato utile?

Soluzione

In generale non importa esattamente quale schema si scrive, è importante che si può identificare il modello al fine di determinare dove si verificano i problemi. Si dà il caso che nel kernel Linux questi sono spesso scelti in modo che possano essere intrappolati se gli indirizzi sono dereferenziati.

Date un'occhiata nel kernel di Linux all'indirizzo include / linux / poison.h . Questo file contiene i valori veleno diversi per molti sottosistemi del kernel differenti. Non v'è alcun valore un veleno che è appropriato.

Inoltre, si potrebbe verificare per-architettura includere i file nell'albero dei sorgenti del kernel di Linux per informazioni su ciò che viene utilizzato su una specifica architettura.

Altri suggerimenti

0xBADC0FFEE0DDF00D

Secondo Wikipedia , BADC0FFEE0DDF00D viene utilizzato su IBM RS / 6000 sistemi a 64 bit per indicare registri della CPU non inizializzati.

La maggior parte dei sistemi a 64 bit attuali consentono di usare solo il più basso 2 48 -2 52 bit di spazio degli indirizzi; elevati bit dell'indirizzo devono essere tutti zero. Alcuni chip (per esempio amd64) consentono anche di utilizzare il più alto 2 48 -2 52 . Indirizzi fuori di questi intervalli non possono mai essere mappati nella memoria accessibile; l'hardware semplicemente non lo permette.

Raccomando, quindi, di utilizzare un valore prossimo a 2 63 , che è in nessun posto vicino uno degli spazi eventualmente-utilizzabili. Se i principali quattro cifre esadecimali sono 7ff8, il valore sarà una doppia precisione in virgola mobile NaN, che è comodo. Quindi il mio suggerito frase carina esadecimale è 0x7FF8BADFBADFBADF.

A proposito, davvero non si desidera utilizzare un valore prossimo a 0, perché questo rende più difficile dire una all'offset dereference di NULL - un accesso membro della struttura, per esempio - da un dereference del modello veleno.

Sto assumendo che hai già scontato NULL (cioè 0 senza il typecast). E 'sicuramente la scelta più sicura, come, in teoria, un puntatore valido potrebbe punto l'indirizzo di memoria 0xDEADBEEF (O qualsiasi altro indirizzo di memoria non-NULL).

0xDEADBEEFBAADF00D potrebbe funzionare.

Non ho una buona scelta per voi, ma ecco un di parole esagonali che è possibile utilizzare per rendere la vostra frase.

Due 0xDEADBEEFs dovrebbero essere abbastanza, credo ..

vedo più risposte sostenendo NULL è una buona scelta, ma non sono d'accordo.

NULL è spesso usato come valore di ritorno valida dalle funzioni. Esso indica un ritorno guasto o un valore sconosciuto. Si tratta di un significato diverso da "puntatore non inizializzato".

Utilizzo di un debugger sul codice e vedere NULL avrebbe poi lasciare due possibilità: il puntatore non è mai stato inizializzato o non era riuscito un'allocazione di memoria

.

Impostazione del puntatore non inizializzato per 0xDEADBEEF o equivalente a 64 bit significa che un puntatore NULL indica un valore di intenzionale.

Dipende dal sistema operativo e l'ambiente, naturalmente. Non credo 0xDEADBEEF è necessariamente una cattiva puntatore in un sistema a 32 bit arbitraria, sia.

Realisticamente, qualsiasi sistema operativo moderno dovrebbe essere l'accesso-proteggere le prime pagine di memoria del processo, in modo da NULL dovrebbe essere un buon valore di puntatore non valido. abbastanza comoda, è già pre-definito per voi.

0x42 potrebbe lavorare su entrambi i 32bit e 64bit? (Si dovrebbe comunque innescare un incidente dal momento che è abbastanza vicino al puntatore NULL, e dato che è piuttosto grande, è probabile che non lo avremo entro un dereference regolare di un campo di struttura con il puntatore struttura di essere NULL).

Mentre il sistema ho lavorato su praticamente gira su piattaforma x86_64, il valore che uso è:

0xDEADBEEFDEADBEEF

I motivi sono i seguenti:

  • Nella piattaforma x86_64, solo il basso per 48 bit sono usati per indirizzi di memoria virtuale in applicazione corrente, cioè qualsiasi valore> 2 ^ 48 dovrebbe funzionare: https://en.wikipedia.org/wiki/X86-64
  • Come 0xDEADBEEF è già molto conosciuta per questo scopo in 32 bit, 64 bit in 0xDEADBEEFDEADBEEF è solo più 'compatibile all'indietro'
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top