<!DOCTYPE html><html><head>
<style type="text/css">body { font-family:'Courier New'; font-size:13px}</style>
</head>
<body>En Wed, 20 Jul 2016 11:28:35 -0500, Juan M. Puertas <soft.sirius@gmail.com> escribió:<br><br><blockquote style="margin: 0 0 0.80ex; border-left: #0000FF 2px solid; padding-left: 1ex"><div dir="ltr"><div class="gmail_default" style="font-family:verdana,sans-serif"> 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.<br></div><div class="gmail_default" style="font-family:verdana,sans-serif"> Saludos :-)</div></div></blockquote><div><br></div><div>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.</div><div><br></div><div>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."</div><div><br></div><div>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:</div><div><br></div><div> 1 function vbSplit(S: string; Delimiter: char): TStrArray;<br> 2 var<br> 3 C: integer;<br> 4 begin<br> 5 repeat</div><div> 6 SetLength(Result, Length(Result) + 1);</div><div> 7 C := Pos(Delimiter, S);</div><div> 8 if C = 0 then</div><div> 9 C := Length(S) + 1;</div><div>10 Result[Length(Result) - 1] := Copy(S, 1, C - 1);</div><div>11 Delete(S, 1, C);</div><div>12 until Length(S) = 0;</div><div>13 end;</div><div><br></div><div>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.</div><div><br></div><div>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:</div><div><br></div><div>function ExtractWord(N: Integer; const S: string; const WordDelims: TSysCharSet): string;</div><div><br></div><div>Es muy fácil su uso, en este caso ComboPais.Items.Add(ExtractWord(1, sLinea, ['/']));</div><div><br></div><div>Y digo de paso por que vbSplit corregida no tiene absolutamente ningún problema :)</div><div><br></div><div>Saludos.</div><div><br></div><div>Jesus Reyes A.</div></body></html>