Ver Mensaje Individual
  #29  
Antiguo 15-10-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Reputación: 38
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.

Con el fin de entender esto, me puse a investigar un poco. Y de lo conocido, mas lo que pude ampliar leyendo, una variable de tipo AnsiString contiene un apuntador que almacena un valor nulo si está vacía o de modo contrario apunta a la dirección del comienzo de una cadena finalizada en nulo al estilo de las cadenas C.

Pero no termina allí, el formato en que se almacena este tipo es:
Código:
[contador de referencias] [longitud de cadena] [cadena + nulo]
El contador de referencias mantiene la cantidad de variables que apuntan a esa cadena en un momento determinado. La longitud de la cadena es almacenada de forma similar a como lo hacía Pascal y por último sigue la cadena en si misma, finalizada en nulo como en C. Lo que hace que este tipo sea una especie de tipo híbrido entre Pascal y C.

El contador de referencias se incrementa cada vez que una cadena es asignada a una variable y se decrementa cuando deja de hacerlo. De este modo cuando el contador llega a cero la memoria previamente reservada es liberada de forma automática; del mismo modo es liberada cuando sale de su ámbito (al estilo de C++). Las variables de este tipo también se inicializan como cadenas vacías de forma automática.

Por último cuando se concatena carácter a carácter, es posible que se libere y reasigne memoria en cada asignación. De lo que resulta, por ejemplo, que es mas eficiente hacer:
Código Delphi [-]
  SetLength(s, 15);
  FillChar(s[1], 15, Ord(' '));
que:
Código Delphi [-]
  for i := 1 to 15 do str := str + ' ';

Haciendo unas pruebas pude pude lograr que se produzca error que buscaba:
Código Delphi [-]
procedure foo(const str: string);
var
  s: string;
  i: Integer;
begin
  for i := 1 to 100 do s := s + str[i];
end;

// Llamada que funciona
procedure TForm1.btnWithoutErrorClick(Sender: TObject);
var
  str: string;
begin
  str := #0;  // o inicializada con cualquier caracter
  foo(str);
end;

// Llamada que produce error
procedure TForm1.btnWithErrorClick(Sender: TObject);
var
  str: string;
begin
  str := EmptyStr; // u omitiendo la línea
  foo(str);
end;
y como se puede ver, sucede cuando el argumento no fue previamente inicializado.

Por último, la función del mensaje #9, resistió todas mis pruebas sin generar ningún error.

En definitiva, no encontré la alusión concreta que buscaba, pero sé un poco mas al respecto .

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Última edición por ecfisa fecha: 15-10-2015 a las 20:03:29.
Responder Con Cita