Master,
Parafraseando a Matias Prats en el comercial de los seguros: "Permíteme que insista",
En el código de la función hb_itemUnShareString, el duplicado se hace solo cuando es realmente necesario, porque hay dos variables apuntando al mimo trozo de memoria. El trozo de código que hace el alloc está dentro de un IF que dice:
- Code: Select all Expand view RUN
if( pItem->item.asString.allocated == 0 || hb_xRefCount( pItem->item.asString.value ) > 1 )
el hb_xRefCount es el contador de referencias a un determinado bloque, y es lo que te había puesto en el ejemplo de a:' 'XXX'; b:= a : este codigo no genera dos bloques de memoria rellenos con 'XXX', sino uno solo, y a y b apuntan al mismo, y el bloque tiene un refcount de 2.
Las advertencias de modificar los bloques con punteros obtenidos con hb_itemGetCPtr se refieren justo a eso. Supongamos que tenemos una funcion CambiaPorY() que modifica el segundo byte a 'Y' de la cadena pasada por referencia, usando
hb_itemGetCPtr . Si hago
a:= 'XXX'
b:= a
CambiaPorY( @a ) // a es ahora 'XYX'
? b // Imprimirá 'XYX', es decir se verá afectada por las modificaciones hechas en otra variable.
Si uso hb_itemUnShareString (supongo que de ahí viene lo de UNSHARE)
a:= 'XXX'
b:= a
CambiaPorYconUnshare( @a ) // a es ahora 'XYX'
? b // Imprimirá 'XXX', porque antes de obtener el puntero separó los buffers, que es el alloc que hacías referencia.
Bueno, te digo para que es todo este rollo: esto es para hacer una clase buffer, para evitar los cBuffer+= texto, por ejemplo cuando generamos ficheros xml o similares.
La sucesiva acumulación de cadenas cortas produce un infierno de reallocs, y si no se hace un garbage collect cada tanto te quedas sin memoria. Bueno, no sin memoria, pero si toda la memoria llena de pequeños bloques y ninguno contínuo suficiente para hacer grandes operaciones. El problema se resuelve frecuentemente escribiendo directamente a disco (si el proceso es generar un fichero), pero escribir muchos trocitos impone una sobrecarga en el sistema de E/S, por lo que habia pensado en hacer algo justamente usando esto del buffer.
Hay un post en el foro en inglés donde hablamos respecto del tema, y uno de los compañeros escribió algo que sirve de idea inicial, y que vamos a tratar de mejorar.