2008-09-22 19 views

Respuesta

6

Si está utilizando FastMM4 como su Administrador de memoria, puede verificar que la clase no sea TFreeObject.
O, en un caso más estándar, utilice una rutina que verifique que su objeto es lo que dice que es comprobando la clase VMT.

Ha habido tales funciones ValidateObj hannging alrededor por algún tiempo (por Ray Lischner y Hallvard Vassbotn: http://hallvards.blogspot.com/2004/06/hack-6checking-for-valid-object.html)

Aquí hay otro:

function ValidateObj(Obj: TObject): Pointer; 
// see { Virtual method table entries } in System.pas 
begin 
    Result := Obj; 
    if Assigned(Result) then 
    try 
     if Pointer(PPointer(Obj)^) <> Pointer(Pointer(Cardinal(PPointer(Obj)^) + Cardinal(vmtSelfPtr))^) then 
     // object not valid anymore 
     Result := nil; 
    except 
     Result := nil; 
    end; 
end; 

Actualización: Un poco de precaución ... Lo anterior La función se asegurará de que el resultado sea nulo o un objeto no nulo válido. No garantiza que el Obj siga siendo lo que usted cree que es, en caso de que el Administrador de memoria ya haya reasignado esa memoria previamente liberada.

+1

@update: por lo tanto, en realidad no es una buena idea usarlo, porque dependiendo del administrador de memoria, es probable que su dirección se reutilice. Por lo tanto, no dará una respuesta definitiva. –

+0

Si le dice que el objeto no es válido, esa * es * una respuesta definitiva, ¿no es así? En cuyo caso es útil. Acabo de usar esto y me ayudó a encontrar un error complicado. – awmross

+0

Claro, es por eso que hice esta función: sin falsos positivos cuando encuentra un objeto malo, está garantizado que es malo. Bueno para levantar una bandera en ese caso, pero no puede garantizar que un objeto aún sea válido para que pueda confiar y usarlo. –

0

Desafortunadamente, no hay forma de garantizar al 100% que un puntero a cualquier cosa siga siendo válido, excepto escribiendo minuciosamente el código correcto.

3

No. A menos que use algo como el recuento de referencias o un recolector de basura para asegurarse de que ningún objeto se liberará antes de que tengan cero referencias.

Delphi puede hacer recuento de referencias si utiliza interfaces. Por supuesto, Delphi for .Net tiene un coleccionista de gárgaras.

Como se mencionó, puede utilizar el conocimiento de Delphi o las funciones internas del administrador de memoria para buscar punteros u objetos válidos, pero no son los únicos que pueden darle punteros. Entonces no puedes cubrir todos los punteros incluso con esos métodos. Y también existe la posibilidad de que su puntero vuelva a ser válido, pero se lo entregue a otra persona. Entonces, no es el puntero que estás buscando. Tu diseño no debe confiar en ellos. Usa una herramienta para detectar cualquier error de referencia que hagas.

0

estándar, no ...

Por eso componentes VCL pueden registrarse para ser notificado de la destrucción de un objeto, de modo que puedan eliminar la referencia de la lista hay interna de componentes o simplemente restablecer sus propiedades.

así que si desea asegurarse de que usted no ha conseguido ningún referencias inválidas su son dos opciones:

  • implementar un controlador de notificación destrucción la que cada clase puede suscribirse.
  • Corrija su código de forma que las referencias no se distribuyan a través de diferentes objetos. Por ejemplo, solo puede proporcionar el acceso a la referencia a través de una propiedad de otro objeto. Y en lugar de copiar la referencia a un campo privado, accede a la propiedad del otro objeto.
1

Como han dicho otros, no hay una manera definitiva, pero si administra bien la propiedad, entonces la rutina FreeAndNil se asegurará de que su variable sea nula si no apunta a nada.

1

Por lo general, no es una buena idea comprobar que una referencia sea válida de todos modos.Si una referencia no es válida, su programa se bloqueará en el lugar donde está utilizando la referencia no válida. De lo contrario, la referencia no válida podría durar más tiempo y la depuración se vuelve más difícil.

Aquí hay algunas referencias a por qué es mejor colgarse de una referencia no válida. (Se habla de punteros en Win32, pero las ideas siguen siendo pertinentes):

0

Con el uso de referencias de interfaz (en lugar de referencias a objetos) es posible evitar estos problemas de puntero no válidos porque ya no hay una llamada explícita a Free en su código.

Cuestiones relacionadas