el Guille, la Web del Visual Basic, C#, .NET y más...

Si usas punteros... apúntate esta

[Este artículo es sólo apto para mentes abiertas que usen punteros o hayan querido usarlos o simplemente piensen que con los punteros sr vive mejor, aunque lo parezca, el contenido no es de guasa]

 
Publicado el 13/Ago/2010
Actualizado el 13/Ago/2010
Autor: Guillermo 'guille' Som

Cuidados que debes tener si utilizas punteros, normalmente si usas C/C++ e incluso C# (algunos dirán que Object Pascal también tiene punteros, pero yo no lo uso...).



 

Introducción:

Aunque es un poco al estilo de coña, en realidad es algo que deberías tener en cuenta, y que no solo es válido para los punteros "puros" (los de C/C++) si no para cualquier variable que tenga una referencia a un objeto.

 

Si usas punteros...

 

Te cuento la historia:

El otro día (el día 10, para ser concretos) estaba revisando los mensajes recientes de mis foros y estuve respondiendo a unos cuantos (últimamente hay poca gente que responda a los mensajes, o al menos hay menos que antes, puede que sea porque los que preguntan parece que quieren que le den todo el código resuelto en vez de resolverle "una duda", pero eso sería otro tema, y además más adecuado para mi blog que para este articulo, que si no, va a parecer que estoy echándole la bronca al que hizo la duda que ha motivado que escriba esto... ¡jo, como me enrollo! con razón últimamente no escribo artículos, jejeje).
Como te decía, entre los mensajes que estuve leyendo, porque antes los leo, me encontré con uno del foro de C/C++ que decía lo siguiente:

Hola, a ver si me podeis ayudar, tengo un problema con las variables al usar esta funcion o bien al hacerla a mano:
char *var="HOLA MUNDO";
char *varmin;
 
varmin = var;
 
printf ("ANTES -> PASADA: %s CONVERTIDA: %s\n", var, varmin);
// Aqui el contenido de las dos variables seria "HOLA MUNDO" 

var = strlwr(var);
printf ("PASADA: %s CONVERTIDA: %s\n", var, varmin);
// En cambio aqui el contenido es "hola mundo" en las DOS,
// cuanod en varmin deberia seguir siendo en mayusculas.

Al usar la funcion strlwr o bien hacerme yo una de conversion con tolower tengo el problema de que la variable que le paso cambia a minusculas en todo el programa, cuando lo que necesito es tener un antes y un despues.

A ver si alguien puede ayudarme que ando loco, muchas gracias de antemano.

La cuestión (por si no estás ducho en esto de los punteros), es que al hacer la asignación:

varmin = var

y estar usando punteros, en realidad estas asignando la misma dirección de memoria a las dos variables, por tanto, si haces un cambio en una de ellas también haces el cambio en la otra... pero no por nada mágico, si no porque ambas variables están apuntando al mismo contenido de la memoria.

En este caso, la solución estaría en asignar a varmin un duplicado de lo que tiene la variable var, en C/C++ se puede hacer por medio de funciones como strdup, y esa fue la respuesta que le di al que prengunto.

 

Seguramente "los expertos" dirán que a ellos nunca les ha pasado (ni les pasará) nunca algo como esto, pero... ahí está para que se aplique el parche el que quiera... y lo de aplicar el parche no es nada con segundas intenciones, simplemente es algo que si vas a usar punteros debes tener en cuenta... es decir, si te metes con los punteros, lo mejor que puedes hacer es estar bien informado y procurar no olvidar estas cosas...

 

¿Ocurre esto también en Visual Basic o en cualquier lenguaje de .NET?

Y para aquellos que programan con Visual Basic (cualquier versión, ya sea o no para punto NET) decirles que tampoco están libres, ya que (a su manera) pero Visual Basic también usa punteros, y a más de uno le habrá pasado que al asignar una variable que contiene un objeto de memoria, después hace una copia (asignando simplemente una variable a otra) y se piensan que tienen dos objetos independientes, pero no... no es así... en realidad solo tiene un objeto en memoria, pero mas de una variable que hace "referencia" a ese objeto... sí, las variables a las que asignamos los objetos por referencia (casi todo lo que manipulamos en punto NET) en realidad son punteros a esos objetos.

Un ejemplo para que lo tengas claro.

Nota:
Creo que será mejor explicarlo en otro momento y de forma independiente, ya que puede que a más de uno también le ocurra con Visual Basic o con C#...

Vale, para que no te quedes con la intriga o por si se me olvida... (que es lo más probable que ocurra).

Básicamente es que no debes asignar una variable que contenga una referencia de un objeto a otra variable, al menos si lo que pretendes es hacer una copia independiente, en ese caso, deberías usar el método Clone de los objetos o bien crear una copia si la clase no tiene ese método.

Si tienes esto, puedes comprobar a lo que me refiero:

Dim obj1 As New Cliente
obj1.Nombre = "Antonio"

Dim obj2 As Cliente = obj1

' muestran lo mismo
Console.WriteLine("obj1= {0}, obj2= {1}", obj1.Nombre, obj2.Nombre)

obj2.Nombre = "Juan"

' sigue mostrando lo mismo, pero usando la ultima asignacion
Console.WriteLine("obj1= {0}, obj2= {1}", obj1.Nombre, obj2.Nombre)

Es decir, las dos variables están apuntando a un mismo objeto del tipo Cliente, por tanto, al cambiar el valor del Nombre en una de esas variables, también se cambia en el otro...

 

Espero que te sea de utilidad.

Nos vemos.
Guillermo

P.S.
Esto en realidad no tiene nada que ver en "como hacer algo en punto NET" pero... no sabía donde meterlo, y ya que C# permite el uso de punteros, al menos si se escribe el código en modo INSEGURO, pues... aquí está para el que le sirva.

Las palabras clave podrían ser: punteros, pointers, punteros en C, punteros en C++

P.S.2
En realidad, al intentar extrapolar el problema a VB me di cuenta de que en realidad esto es muy útil para todos los que programan, ya sean con punteros directamente o con los punteros camuflados que hacen "referencia" a objetos...

 



 


La fecha/hora en el servidor es: 22/12/2024 16:55:46

La fecha actual GMT (UTC) es: 

©Guillermo 'guille' Som, 1996-2024