*********
En español
*********
Hola a todos: los consulto por un problema que estoy teniendo con FreePascal desde ayer y por mas que lo pienso no lo puedo resolver. Mi programa tiene 2 clases, "TPadre" y "THijo". Los hijos, como no se el número a priori, están definidos en un array dinámico:
type
pHijo = ^Hijo;
Hijo = class
...
end;
var
Hijos: array of THijo;
El objeto "Padre" tiene un campo de tipo puntero que apunta a los hijos que tiene asociado. Este campo es un array dinámico:
TPadre = class
...
teHijos: array of pHijo
...
end;
(Puede haber varias variables padres, y los hijos pueden estar asignados a mas de un padre, por lo cual no puedo definir el array "Hijos" dentro de TPadre).
Para crear dinámicamente a los hijos, tengo definido el siguiente procedimiento:
procedure CrearHijo(iCod: integer; strNombre: string; Padre: TPadre);
begin
setlength(Hijos, length(Hijos) +1);
Hijos[high(Hijos)]:= THijo.create(iCod, strNombre) ;
VincularHijos(Padre, Hijos[high(Hijos)]);
end;
Donde "VincularHijos" es:
procedure VincularHijos(var Padre: TPadre; var Hijo: THijo);
var
i: integer;
begin
i:=length(Padre.teHijos);
setlength(Padre.teHijos, i+1);
Padre.teHijos[i]:= @Hijo;
end;
En principio funciona bien, no tengo problemas en hacer cosas como:
writeln(Padre.teHijos[i]^.strNombre);
Pero cuando tengo mas de tres hijos creados y asignados al padre, resulta que una instrucción como la anterior me tira error para valores pequeños de "i". Lo raro es que si el array "Hijos" es estático, puedo hacer "Padre.teHijos
^.strNombre" para cualquier hijo, no tengo el problema anterior. Es como si setlength, en el procedimiento "CrearHijos" modificara la ubicación en memoria de los elementos del array (pero no siempre, sinó solo algunas veces).
Para que vean un caso puntual, definido "Hijos" en forma dinámica, le cargué 14 variables "Hijo". Desde "Padre.teHijos[0]^." a "Padre.teHijos[7]^" me tira el error "SIGSEGV Error" en tiempo de ejecución, para los "Padre.teHijos[8]^" a "Padre.teHijos[13]^" el código funciona correctamente.
¿Alguién sabe que puede estar pasando?
PD: Uso Lazarus 0.9.28.2 con fpc 2.2.4 .
****************************************************************
****************************************************************
********************
In (very, very bad) english
********************
Hi: I consult you for a problem I'm having with FreePascal since yesterday and as much as I think I can not solve. My program has 2 class, "TPadre" (Father) and "THijo" (Son). The Hijo object, as no a priori number, are defined in a dynamic array:
:
type
pHijo = ^Hijo;
Hijo = class
...
end;
var
Hijos: array of THijo;
The "Padre" object has a field of type pointer to the "Hijo" that is associated. This field is a dynamic array:
TPadre = class
...
teHijos: array of pHijo
...
end;
(There may be several variables TPadre, and THijo can be assigned to more than one father, so I can not define the array "Hijos" in TPadre).
To dynamically create the "Hijo", I have defined the following procedure:
procedure CrearHijo(iCod: integer; strNombre: string; Padre: TPadre);
begin
setlength(Hijos, length(Hijos) +1);
Hijos[high(Hijos)]:= THijo.create(iCod, strNombre) ;
VincularHijos(Padre, Hijos[high(Hijos)]);
end;
"VincularHijos" is:
procedure VincularHijos(var Padre: TPadre; var Hijo: THijo);
var
i: integer;
begin
i:=length(Padre.teHijos);
setlength(Padre.teHijos, i+1);
Padre.teHijos[i]:= @Hijo;
end;
In principle it works well, I have no trouble doing things like:
writeln(Padre.teHijos[i]^.strNombre);
But when I have more than three "THijo" created and assigned to the "Padre", a statement like the above throw me error for small values of "i". The strange thing is that if the array "Hijos" is static, I can do "Padre.teHijos
^. StrName" for any "THijo", I don´t have the above problem. Is as if SetLength, in the procedure "CrearHijos", modify the memory location of array elements (but not always, but only a few times).
To see a punctual case, I defined as "THijo", 14 variables in the dynamic array "Hijos". From "Padre.teHijos - ^" to "Padre.teHijos [7] ^" I throw the error "Error SIGSEGV" at run time, from "Padre.teHijos [8] ^" to "Padre.teHijos [ 13] ^ "the code works correctly.
Does anyone know what could be happening?
PD: I use Lazarus 0.9.28.2 with fpc 2.2.4 .