que punteros puntero funciones ejemplo declaracion con cadenas aritmetica apuntadores c++

c++ - funciones - punteros a cadenas



¿Qué sucederá cuando llame a una función miembro en un puntero de objeto NULL? (6)

El comportamiento más probable, en la mayoría de las computadoras modernas, es que se ejecutará e imprimirá "diversión" porque:

  • C ++ no comprueba si el puntero es NULL antes de llamar a la función
  • fun() no es virtual, por lo que no es necesario hacer referencia a un vtable para llamar a fun()
  • fun() nunca accede a ninguna variable miembro en A por lo que no necesita desreferenciar el nulo de this puntero.

Me dieron lo siguiente como una pregunta de entrevista:

class A { public: void fun() { std::cout << "fun" << std::endl; } }; A* a = NULL; a->fun();

¿Qué sucederá cuando se ejecute este código y por qué?

Ver también:


Es un comportamiento indefinido, por lo que cualquier cosa puede pasar.

Un posible resultado sería que simplemente imprime "fun" ya que el método no accede a las variables miembro del objeto al que se llama (no es necesario acceder a la memoria donde supuestamente vive el objeto, por lo que las violaciones de acceso no se realizan). necesariamente ocurre).


Lo he intentado varias veces, todo el tiempo la salida se vuelve "divertida", esto es porque la fun función es independiente de la instancia a . mientras llamas a->fun(); a puntos a 0 por lo que este es un comportamiento indefinido, pero en la mayoría de los compiladores no debería producirse un bloqueo.



Según el estándar, esto es un comportamiento indefinido y, por lo tanto, algo muy malo. En realidad, la mayoría de las plataformas de programación (tanto para X86 como para otras arquitecturas) funcionarán bien.

¿Por qué? Considere cómo se implementan las funciones de clase en C ++. Esta no es una función virtual, por lo tanto, esto puede ser una llamada estática a una dirección conocida. En el ensamblaje x86, podemos ver esto como

mov A, 0 mov ecx, A call a__fun

ya que a__fun no requiere datos de instancia, aunque reciba un null este puntero, no pasará nada.

Todavía el código de mierda y cualquier compilador gritarán, pero se puede ejecutar.


Tres puntos pueden ayudar:

1) Todas las funciones se almacenan en el código o la sección de texto.

2) Las funciones no virtuales se resuelven al momento de cumplir.

3) Al llamar a las funciones miembro de la clase, pasamos el objeto actual como this puntero a esa función.

Al llegar a su pregunta, aquí la función de fun() ya está en la memoria (sección de código / sección de texto). Como función fun() no es virtual, se resolverá en el momento de cumplimiento (es decir, para esta línea saltará a la instrucción X en la sección de código con this puntero como NULL ). Como no se usa / llama ninguna función miembro ni función virtual en la función fun() , funciona bien.