InicioArticulos y noticiasBases de datosProgramaciónForosInternetServiciosContratacionEmail
Tutorial C#
Introduccion a C#
Programacion con C#
Fundamentos de C#
Operadores
Instrucciones
Estrcuturas de control.
Definición de clases
Creación de objetos
Herencia y métodos virtuales
Polimorfismo
Ocultación de miembros
Miembros de tipo
Encapsulación
Espacios de nombres
Importación de espacios de nombres
Espacio de nombres distribuidos
Variables y tipos de datos
Tablas unidimensionales
Tablas multidimensionales
La clase System.Array
Cadenas de texto
Constantes
Orden de inicialización de variables
Métodos
Métodos externos
Constructores
Destructores
Propiedades
Indizadores
Redefinición de operadores
Delegados y eventos
La clase MulticastDelegate
Llamadas asíncronas
Implementación interna de los delegados
Eventos
Estructuras
Boxing y unboxing
Constructores de estructuras
Enumeraciones
Interfaces
Excepciones
Otras instrucciones
Atributos
Definición de nuevos atributos
Lectura de atributos en tiempo de ejecución
Atributos de compilación
Pseudoatributos
Código inseguro
Definición de punteros
Manipulación de punteros
Operadores relacionados con código inseguro
Fijación de variables apuntadas
Novedades de C# 2.0
Genéricos
Tipos parciales
Iteradores
Mejoras en la manipulación de delegados
Tipos anulables
Modificadores de visibilidad de bloques get y set
Clases estáticas
Referencias a espacios de nombres
Supresión temporal de avisos
Atributos condicionales
Incrustación de tablas en estructuras
Modificaciones en el compilador
También puedes ver ...
SubVersion y Visual Studio
Encriptación con AES Rijndael - Ejemplo
TripleDES - Un ejemplo practico en C#
Insertar una marca de agua en documentos PDF
Serialización: XmlSerializer y BinaryFormater
Handler para manipular imagenes
Conversiones de tipos personalizadas (VB y C#)
Compresión por gzip y deflate
La página Web que está abriendo contiene tanto elementos seguros como no seguros.
Cómo insertar un fichero .xml en un campo de tipo XML de SQL server 2005 o 2008


Fijación de variables apuntadas

    Aunque un puntero sólo puede apuntar a datos de tipos que puedan almacenarse completamente en pila (o sea, que no sean ni objetos de tipos referencia ni estructuras con miembros de tipos referencia), nada garantiza que los objetos apuntados en cada momento estén almacenados en pila. Por ejemplo, las variables estáticas de tipo int o los elementos de una tabla de tipo int se almacenan en memoria dinámica aún cuando son objetos a los que se les puede apuntar con punteros.

    Si un puntero almacena la dirección de un objeto almacenado en memoria dinámica y el recolector de basura cambia al objeto de posición tras una compactación de memoria resultante de una recolección, el valor almacenado en el puntero dejará de ser válido. Para evitar que esto ocurra se puede usar la instrucción fixed, cuya sintaxis de uso es:


fixed(
<tipo> <declaraciones>)
      <instrucciones>

    El significado de esta instrucción es el siguiente: se asegura que durante la ejecución del bloque de <instrucciones> indicado el recolector de basura nunca cambie la dirección de ninguno de los objetos apuntados por los punteros de tipo <tipo> declarados. Estas <declaraciones> siempre han de incluir una especificación de valor inicial para cada puntero declarado, y si se declaran varios se han de separar con comas.

    Los punteros declarados en <declaraciones> sólo existirán dentro de <instrucciones>, y al salir de dicho bloque se destruirán. Además, si se les indica como valor inicial una tabla o cadena que valga null saltará una NullReferenceException. También hay que señalar que aunque sólo pueden declarase punteros de un mismo tipo en cada fixed, se puede simular fácilmente la declaración de punteros de distintos tipos anidando varios fixed.

    Por otro lado, los punteros declarados en <declaraciones> son de sólo lectura, ya que si no podría cambiárseles su valor por el de una dirección de memoria no fijada y conducir ello a errores difíciles de detectar.

    Un uso frecuente de fixed consiste en apuntar a objetos de tipos para los que se puedan declarar punteros pero que estén almacenados en tablas, ya que ello no se puede hacer directamente debido a que las tablas se almacenan en memoria dinámica. Por ejemplo, copiar usando punteros una tabla de 100 elementos de tipo int en otra se haría así:


 class CopiaInsegura
 {
  public unsafe static void Main()
  {
   int[] tOrigen = new int[100];
   int[] tDestino = new int[100];
   fixed (int * pOrigen=tOrigen, pDestino=tDestino)
   {
    for (int i=0; i<100; i++)
     pOrigen[i] = pDestino[i];
   }
  }
 }

    Como puede deducirse del ejemplo, cuando se inicializa un puntero con una tabla, la dirección almacenada en el puntero en la zona <declaraciones> del fixed es la del primer elemento de la tabla (también podría haberse hecho pOrigen = &tOrigen[0]), y luego es posible usar la aritmética de punteros para acceder al resto de elementos a partir de la dirección del primero ya que éstos se almacenan consecutivamente.

    Al igual que tablas, también puede usarse fixed para recorrer cadenas. En este caso lo que hay que hacer es inicializar un puntero de tipo char * con la dirección del primer carácter de la cadena a la que se desee que apunte tal y como muestra este ejemplo en el que se cambia el contenido de una cadena "Hola" por "XXXX":


 class CadenaInsegura
 {
  public unsafe static void Main()
  {
   string s="Hola";
   Console.WriteLine("Cadena inicial: {0}", s);
   fixed (char * ps=s)
   {
    for (int i=0;i<s.Length;i++)
     ps[i] = 'A';
   }
   Console.WriteLine("Cadena final: {0}", s);
  }
 }

    La salida por pantalla de este último programa es:

      Hola

      AAAA

    La ventaja de modificar la cadena mediante punteros es que sin ellos no sería posible hacerlo ya que el indizador definido para los objetos string es de sólo lectura.

    Cuando se modifiquen cadenas mediante punteros hay que tener en cuenta que, aunque para facilitar la comunicación con código no gestionado escrito en C o C++ las cadenas en C# también acaban en el carácter ‘\0’, no se recomienda confiar en ello al recorrerlas con punteros porque ‘\0’ también puede usarse como carácter de la cadena. Por ello, es mejor hacer como en el ejemplo y detectar su final a través de su propiedad Length.

    Hay que señalar que como fixed provoca que no pueda cambiarse de dirección a ciertos objetos almacenados en memoria dinámica, ello puede producir la generación de huecos en memoria dinámica, lo que tiene dos efectos muy negativos:

  • El recolector de basura está optimizado para trabajar con memoria compactada, pues si todos los objetos se almacenan consecutivamente en memoria dinámica crear uno nuevo es tan sencillo como añadirlo tras el último. Sin embargo, fixed rompe esta consecutividad y la creación de objetos en memoria dinámica dentro de este tipo de instrucciones es más lenta porque hay que buscar huecos libres.
  • Por defecto, al eliminarse objetos de memoria durante una recolección de basura se compacta la memoria que queda ocupada para que todos los objetos se almacenen en memoria dinámica. Hacer esto dentro de sentencias fixed es más lento porque hay que tener en cuenta si cada objeto se puede o no mover.

    Por estas razones es conveniente que el contenido del bloque de instrucciones de una sentencia fixed sea el mínimo posible, para que así el fixed se ejecute lo antes posible.


Inicio | Tutorial C# Operadores relacionados con código inseguroTutorial C#Novedades de C# 2.0 Versión para imprimir Foros de consulta


Añadir comentario ... Para preguntar utiliza los foros
Autor:

Título:


Para preguntar utiliza los foros.



Inicio | Tutorial C# Operadores relacionados con código inseguroTutorial C#Novedades de C# 2.0 Versión para imprimir

Fijación de variables apuntadas
Autor: José Antonio González Seco
Visitas: 6899 Fecha de publicación: 07/12/2006
José Antonio es experto en tecnologias Microsoft. Imparte cursos y conferencias en congresos sobre C# y .NET en Universidades de toda España (Sevilla, Barcelona, San Sebastián, Valencia, Oviedo, etc.) en representación de grandes empresas como Microsoft.




Visitas: 86 | Comentarios: 2 | Archivo: Articulos
02/02/2010 iPad vs Telesketch
Visitas: 791 | Comentarios: 2 | Archivo: Articulos
Categorias: Humor
Visitas: 739 | Comentarios: 3 | Archivo: Articulos
Visitas: 3134 | Comentarios: 2 | Archivo: Articulos
Categorias: C#
Visitas: 14487 | Comentarios: 7 | Archivo: Articulos
Categorias: C#|Seguridad
Visitas: 1474 | Comentarios: 3 | Archivo: Articulos
Visitas: 690 | Comentarios: 2 | Archivo: Articulos
Visitas: 368 | Comentarios: 0 | Archivo: Articulos
Visitas: 2006 | Comentarios: 2 | Archivo: Articulos
Categorias: C#

Útimos temas recibidos en los foros ...
certificado pensiones horizonte por angela patricia rodriguez ... [Actualidad] 135 26/01/2010
pensiones por eduard ... [Visual Basic 6.0] 0 11/03/2010
Manual Visual Studio.NET por Shiko ... [Visual Basic .NET] 41 26/10/2006
cap de setmana genial por ramón ... [Java] 0 11/03/2010
cetificado de pension por RICARDDO RAFAEL SOLANO ORZCO ... [Actualidad] 0 11/03/2010
solicitud de aifiliacion a porvernir por julios ... [Actualidad] 2 11/03/2010
Solicitar el certificado de pensiones de Abelardo Alfonso Serrano Banegas C.C. 18 971 771 de Curumani Cesar por Marta ... [Actualidad] 0 11/03/2010
Solicitud certificado de afiliaciones a pensiones y cesantias proteccion por hz ... [Actualidad] 50 10/02/2010
cerificado fondo horizonte de pensiones y cesantias por carlos fideligno torres herrera ... [Actualidad] 146 18/01/2010
certificado de afiliación de pensiones y cesantias por secre ... [Actualidad] 109 28/01/2010
certificado de fondos de pensiones horizonte por mona ... [Actualidad] 5 03/03/2010
Certificado de afiliacion AFP (PENSIONES) Horizonte por Sandris ... [Actualidad] 68 30/01/2010

Access CGI JSP ORACLE UNIX
Actualidad HTML/DHTML/XHTML LINUX PHP Visual Basic .NET
ASP ISAPI MS DOS Power Builder Visual Basic 6.0
ASP.NET Java mySQL SQL WIN 98/NT/2000/XP
C# JavaScript Opinion SQL Server

devjoker  Te recomendamos además ...
05/07/2007 Consultar datos en Transact SQL    forma parte de...Tutorial de Transact SQL
12/01/2006 Introducción a PLSQL    forma parte de...Tutorial PL/SQL
19/10/2006 Llamadas asíncronas    forma parte de...Tutorial C#
14/07/2006 Tablas PL/SQL    forma parte de...Tutorial PL/SQL
22/10/2005 Introducción SQL    forma parte de...Tutorial SQL
18/10/2005 Enviar emails a través de un servidor SMTP autenticado con Java
11/12/2006 Novedades de C# 2.0    forma parte de...Tutorial C#
11/12/2006 Genéricos    forma parte de...Tutorial C#
11/12/2006 Tipos parciales    forma parte de...Tutorial C#
22/10/2005 Actualización de datos. UPDATE    forma parte de...Tutorial SQL

 

Encuesta
¿A que perfil te adaptas mejor?




[Ver] [Votar]