[Lazarus-es] uso de SetLength

Jesus Reyes A. jesusrmx en gmail.com
Mie Jul 20 21:02:05 CEST 2016


En Wed, 20 Jul 2016 11:28:35 -0500, Juan M. Puertas  
<soft.sirius en gmail.com> escribió:

> Según el artículo de la Wiki, cuando se sale del procedimiento o función  
> en el que se encuentra SetLength, la memoria >se libera automáticamente.
> Saludos :-)

Esto es así para las variables declaradas dentro de las funciones o  
procedimientos, en el caso que nos ocupa hoy, estamos hablando de un  
resultado de tipo array dinámico, "Result" en éste caso no es una variable  
común y corriente.

De hecho hace poco, a finales de junio pasado, ha tenido lugar una  
conversación que resulta esclarecedora, una persona pregunta: ¿Qué Tipos  
necesitamos inicializar a null/nil/zero/'' cuando son el resultado de una  
función? un desarrollador de FPC responde: "Los resultados de todos los  
Tipos (auto manipulados o no) necesitan ser ajustados a 'vacio' si quieres  
regresarlos como un resultado 'vacio'" y mas adelante en la conversación:  
"Como regla general, los resultados de una función no contienen un valor  
predecible al entrar en la función."

Esto aplica directamente en el caso que nos ocupa pues en la función  
vbSplit el resultado de la función en ningún momento es inicializado y por  
lo que acabamos de leer, el resultado contiene un valor indefinido. He  
aquí la función en cuestión:

  1 function vbSplit(S: string; Delimiter: char): TStrArray;
  2 var
  3   C: integer;
  4 begin
  5   repeat
  6     SetLength(Result, Length(Result) + 1);
  7     C := Pos(Delimiter, S);
  8     if C = 0 then
  9       C := Length(S) + 1;
10     Result[Length(Result) - 1] := Copy(S, 1, C - 1);
11     Delete(S, 1, C);
12   until Length(S) = 0;
13 end;

Según lo anterior, la línea 6 Length(Result) es indefinido (para todo  
propósito "indefinido" aquí se refiere a un detalle interno que depende de  
la implementación actual en el compilador). En mi opinión SetLength se  
esta utilizando correctamente solo que antes que nada el resultado debe  
ser inicializado y para ello basta insertar entre las lineas 5 y 6 un  
SetLength(Result, 0); y listo.

Ya de paso y encarrerado me atrevo a sugerir algo, la unidad StrUtils  
proporcionada por la RTL de FPC contiene muchas funciones entre ellas esta  
ExtractWord que tiene la siguiente declaración:

function ExtractWord(N: Integer; const S: string; const WordDelims:  
TSysCharSet): string;

Es muy fácil su uso, en este caso ComboPais.Items.Add(ExtractWord(1,  
sLinea, ['/']));

Y digo de paso por que vbSplit corregida no tiene absolutamente ningún  
problema :)

Saludos.

Jesus Reyes A.
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus-es/attachments/20160720/11a69abf/attachment-0001.html>


More information about the Lazarus-es mailing list