2010-11-24 23 views
7

Digamos que tiene algo como esto:¿Está buscando una referencia nula?

int& refint; 
int* foo =0; 
refint = *foo; 

¿Cómo puede usted verificar si la referencia es NULL para evitar un choque?

+7

arrastra el desarrollador que escribió que en un cuarto oscuro con una silla y una luz que brilla en él. Luego los quemas con cigarrillos hasta que se arrepientan. –

Respuesta

11

No se puede inicializar tarde una referencia como esa. Tiene que ser inicializado cuando se declara.

En Visual C++ me sale

error C2530: 'refint': referencias debe ser inicializado

con su código.

Si 'corrige' el código, el bloqueo (comportamiento estrictamente indefinido) ocurre en el tiempo de uso de referencia en VC++ v10.

int* foo = 0; 
int& refint(*foo); 
int i(refint); // access violation here 

La forma de hacerlo seguro es verificar el puntero en la inicialización de referencia o el tiempo de asignación.

int* foo =0; 
if (foo) 
{ 
    int& refint(*foo); 
    int i(refint); 
} 

pesar de que todavía no garantiza foo puntos a la memoria utilizable, ni que éste sigue siendo así que mientras que la referencia es en su alcance.

+0

"el bloqueo ocurrirá en el momento de inicio de referencia" - ¿promesa? ;-) –

+0

No es necesario que el bloqueo (y, a menudo, no) suceda en el momento de inicio de la referencia. con UB, cualquier cosa podría pasar, incluido el bloqueo. –

+0

@Charles, verifiqué mis suposiciones en el depurador y edité. Solo falla en VC++ cuando uso la referencia. UB todo el tiempo ... –

5

No tiene, para el momento en que tiene una referencia "nula" usted ya tiene un comportamiento indefinido. Siempre debe verificar si un puntero es nulo antes de tratar de formar una referencia desmarcando el puntero.

(Su código es ilegal, no se puede crear una referencia sin inicializar y tratar de obligar a éste mediante la asignación, sólo se puede obligar a éste durante la inicialización.)

4

En general, no se puede.

Quienquiera que "crea una referencia nula" (o lo intenta, debería decir) ya ha invocado el comportamiento indefinido, por lo que el código podría (o no) bloquearse antes de que tenga la oportunidad de verificar algo.

El que creó la referencia debería haber hecho:

int *foo = 0; 
if (foo) { 
    int &refint = *foo; 
    ... use refint for something ... 
} 

Normalmente se considera el problema de la persona que llama si se han escrito *foo cuando foo es nulo, y no es responsabilidad de una función para comprobar si hay ese tipo de error en el código de otras funciones. Pero puedes ensuciar cosas como assert(&refint); a través de tu código. Podrían ayudar a detectar los errores cometidos por las personas que llaman, ya que después de todo para cualquier función que escriba existe una posibilidad razonable de que la persona que llama sea usted mismo.

-5

No es necesario, las referencias no pueden ser nulas.

Lea el manual.

0

Para que la compilación de código anterior, tendrá que cambiar el orden:

int* foo =0; 
int& refint = *foo; // on actual PCs, this code will crash here 

(Puede haber más viejas arquitecturas de procesador o de tiempo de ejecución en que esto funcionó.)

0

....diciendo todo lo anterior, si haces quiere tener una referencia nula, utiliza boost::optional<>, funciona como un encanto ..

1

Todas las respuestas anteriores son correctas, pero si por alguna razón usted quiere hacer esto pensé al menos una persona debe dar una respuesta. Actualmente estoy tratando de rastrear una mala referencia en algún código fuente y sería útil ver si alguien ha eliminado esta referencia y la ha establecido como nula en algún momento. Con suerte, esto no generará muchos votos a la baja.

#include <iostream> 
    int main() 
    { 
     int* foo = nullptr; 
     int& refint = *foo; 

     if(&refint == nullptr) 
      std::cout << "Null" << std::endl; 
     else 
      std::cout << "Value " << refint << std::endl; 
    } 

Salida:

nulo

+0

Nota: el resultado es nulo en este caso porque int * foo; acaba de pasar a ser nullptr. Como no está inicializado, podría ser cualquier cosa. Lo inicializaría a nullptr. –

+0

@LennartRolland Buen punto, arreglado. – marsh

Cuestiones relacionadas