Pregunta

tuve este error desagradable que desapareció en el pasado, pero ahora, después de algún tiempo volvió.

He dos objetos tsam (derivado de TPersistent) creado y se carga en un objeto TAsmJob (derivado de TObjectList).

En tiempo de ejecución, una forma crea una TStringGrid y luego el AsmJob que crea esos dos objetos SAM (y la carga de algunos datos desde el disco en cada uno de ellos). El AsmJob también se le asigna a la red. Cuando la forma es destruida, la rejilla se encarga de la AsmJob liberándolo, lo que libera los objetos tsam. Aquí está el problema:. El primer objeto es liberado withot problemas, pero la segunda se muere cuando su método heredado (en Destruye destructor) se llama

Yo uso FreeAndNil en todo el programa para liberar a los objetos. Los objetos no son tsam NIL !!!!! Por lo tanto, este es el primer intento de liberar a los objetos. Incluso los datos dentro de los objetos es consistente.

La columna vertebral del programa es el siguiente:

**Create:**

Form -> StringGrid
     -> AsmJob -> Sam1, Sam2
StringGrid.AsmJob:= AsmJob;


**Free:**

Form -> StringGrid -> AsmJob -> Sam1, Sam2

Realmente no entiendo donde intento hacer doble libre o sobrescribir el objeto después de que ha sido puesto en libertad.


editar

Algunos de los errores que tengo:

  • FastMM ha detectado un error durante una bloque libre operación de exploración. FastMM detecta que un bloque ha sido modificado después de ser liberado.

  • FastMM ha detectado un error durante una bloque libre operación de exploración. El bloque cabecera se ha corrompido.

Detalle:

The current thread ID is 0x19C, and the stack trace (return addresses) leading to this error is: 
402E77 [System][@FreeMem] 
4068DC [System][@DynArrayClear] 
405E2D [System][@FinalizeArray] 
405D31 [System][@FinalizeRecord] 
40432F [System][TObject.CleanupInstance] 
404272 [System][TObject.FreeInstance] 
404641 [System][@ClassDestroy] 
4D313E [UnitSam.pas][TSam.Destroy][297] 
4042BF [System][TObject.Free] 
4149ED [SysUtils][FreeAndNil] 
4D9C0A [UnitAsmJob.pas][UnitAsmJob][TAsmJob.Destroy][180]  

Tengo todas las opciones "depuración" habilitadas en el IDE, incluyendo el "rango de control". Además, el FastMM4 se establece en el modo de depuración muy agresivo. Sin FastMM o fuera del depurador el programa se ejecuta muy bien - pero aún sé que no quiere decir que el error ya no está allí. En realidad funcionó (probablemente) por más de un un año, hasta que haya instalado FastMM.


editar

Gracias a todo el mundo. No me siento estoy moviendo un poco en la buena dirección.

La estructura del programa es más complicado que ofrece sólo la columna vertebral para mantener el post original pequeña. Pero qué diablos, que ya tiene más grande :) Por lo tanto, esos objetos tsam se utilizan para cargar datos desde el disco. Un archivo en cada objeto. Ellos están haciendo también algo de validación y procesamiento de datos. Para cada uno de estos tsam también tengo un objeto gráfico que muestra en la pantalla (gráficamente) los datos contenidos en los objetos de Tsam. Cada línea de la TStringGrid también muestran los datos en tsam, pero textualmente.

Una pregunta que tengo: si rompo el programa en pedazos más pequeños para averiguar dónde está el error, seguirá apareciendo el error? O es posible que aparezcan sólo en esta configuración particular?


Respuesta a "¿cómo el AsmJob se asignan a TStringGrid para que el TStringGrid destruye la AsmJob, nos muestras?"

MyGrid = TStringGrid
  public 
    AsmJob: TAsmJob; 
  end; 

A continuación, en algún lugar del TForm.Create (la forma que tiene el Grid), hago

MyGrid.AsmJob=AsmJob; 

y en el destructor de la MyGrid hago:

begin 
  FreeAndNil(AsmJob); 
  inherited 
end;
¿Fue útil?

Solución

Este error significa que el código dañado estructuras de administrador de memoria interna. Su pila de llamadas representa el punto, cuando se detecta esta MM. Esto no es ruta de error o algo relacionado con él. El error real ocurre antes de este momento. Se puede o no estar relacionado con las clases mencionadas.

Usted debe tratar de usar "errores de prueba de alcance" opción (Don 't olvides de hacer Generar, no compila) y FastMM en modo de depuración completa (con CheckHeapForCorruption, CatchUseOfFreedInterfaces и opciones DetectMMOperationsAfterUninstall habilitado) .

También puede encender FullDebugModeScanMemoryPoolBeforeEveryOperation variable global, para conseguir un error casi inmediatamente después de que ocurre un problema, pero esta opción ralentiza su ejecución MUCHO.

Probablemente la mejor opción es ScanMemoryPoolForCorruptions llamada periódicamente. Llamarlo en un solo lugar. Tienes un error? Llamar antes. Todavía tiene un error? Llamarlo más pronto de nuevo. ¿No hay error? Su problema se encuentra en algún lugar entre esas últimas llamadas. Ahora puede utilizar la variable FullDebugModeScanMemoryPoolBeforeEveryOperation para obtener la ubicación exacta. Sólo tienes que encender solamente en el área de este código y apagarlo inmediatamente después de la misma.

Hay un error muy similar: "FastMM detecta que un bloque se ha modificado después de ser liberado". En este caso, su código modifica no las estructuras internas, pero otra memoria, que no se utiliza en absoluto ( "memoria libre").

Por cierto, el error no se doble gratis! Si se trata de una llamada de doble conexión, FastMM le dirá que de forma explícita (es fácil de detectar, ya que usted está tratando de liberar no-usado o no-existido bloque de memoria): "Se ha hecho un intento de conexión / reasignar una bloque no asignado".

Otros consejos

Una cabecera de bloque conseguir dañado por lo general significa que algo ha sido sobrescribir memoria, por lo general haciendo algún tipo de operación insegura. ¿Está utilizando punteros primas o código ensamblador en cualquiera de sus tareas? Además, si usted tiene la verificación del rango y la comprobación de los límites apagados, intente encenderlas y reconstrucción. Ellos pueden ayudar a capturar una gran cantidad de este tipo de problema.

Es posible que haya una carrera lógica en alguna parte del código en la que un objeto se está escribiendo a medida que está siendo liberado. Añadir nulo cheques y otros mecanismos IPC (listas de bloqueo, etc.) para asegurarse de que no es el caso.

Otra opción podría ser la subclase el código para agregar el registro en ella -. Y comprobar si se está accediendo de forma secuencial objetos

Un par de cosas y yo estoy pidiendo porque no puedo ver su código.

Dado el siguiente código:

procedure TForm1.FormCreate(Sender: TObject);
var
   wObjLst : TObjectList;
begin
   wObjLst := TObjectList.Create;
   try
      wObjlst.OwnsObjects := true;
      wObjlst.Add(TPersistent.Create);
      wObjlst.Add(TPersistent.Create);
   finally
      freeandnil(wObjlst);
   end;
end;

Esto funciona con el error a cabo.

Usted afirma que

  

En tiempo de ejecución, una forma crea una TStringGrid y luego el AsmJob cuales   crea esos dos objetos SAM (y cargar algunos datos desde el disco en cada una de   ellos). El AsmJob también se le asigna a la red. Cuando la forma es destruida,   la rejilla se encarga de la AsmJob liberándola, que libera al tsam   objetos. Aquí está el problema: el primer objeto se libera withot problemas   pero la segunda se muere cuando su método heredado (en Destruye   destructor) se llama.

Mi primera pregunta es ¿cómo el AsmJob se asignan a TStringGrid para que el TStringGrid destruye la AsmJob, nos muestras?

En segundo lugar, ¿por qué crear un descendiente de TObjectList conseguirlo para almacenar dos objetos y luego liberarlos libre en lugar de crear por sí mismo y dejar que el TObjectList ellos destruyen como se muestra arriba.

La otra cosa a intentar es descargar el paquete completo de FastMM4 fastmm.sourceforge.net , instalar y utilizar el archivo DLL fulldebug de rastrear exactamente qué objeto está fallando. Usted y yo está asumiendo que es uno de los objetos SAM y que puede o no ser.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top