Dominando código no seguro en C#: Guía de punteros y gestión de memoria
C# permite usar variables puntero en una función o bloque de código cuando se marca con el modificador unsafe. El código no seguro o código no administrado es un bloque de código que usa una variable puntero.
Punteros
Un puntero es una variable cuyo valor es la dirección de otra variable, es decir, la dirección directa de la ubicación de memoria. Al igual que cualquier variable o constante, debes declarar un puntero antes de usarlo para almacenar una dirección de variable.
La forma general de una declaración de puntero es:
tipo *nombre-var;
Declaraciones de puntero válidas:
int *ip; // puntero a un entero double *dp; // puntero a un double float *fp; // puntero a un float char *ch; // puntero a un carácter
El siguiente ejemplo ilustra el uso de punteros en C# con el modificador unsafe:
using System;
namespace AplicacionCodigoNoSeguro {
class Programa {
static unsafe void Main(string[] args) {
int var = 20;
int* p = &var;
Console.WriteLine("Dato: {0} ", var);
Console.WriteLine("Dirección: {0}", (int)p);
Console.ReadKey();
}
}
}
Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:
Dato: 20 Dirección: 99215364
En lugar de declarar un método completo como unsafe, también puedes declarar solo una parte del código como unsafe. El ejemplo en la siguiente sección muestra esto.
Recuperar el valor de dato usando un puntero
Puedes recuperar el dato almacenado en la ubicación referenciada por la variable puntero, usando el método ToString(). El siguiente ejemplo demuestra esto:
using System;
namespace AplicacionCodigoNoSeguro {
class Programa {
public static void Main() {
unsafe {
int var = 20;
int* p = &var;
Console.WriteLine("Dato: {0} ", var);
Console.WriteLine("Dato: {0} ", p->ToString());
Console.WriteLine("Dirección: {0} ", (int)p);
}
Console.ReadKey();
}
}
}
Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:
Dato: 20 Dato: 20 Dirección: 77128984
Pasar punteros como parámetros a métodos
Puedes pasar una variable puntero a un método como parámetro. El siguiente ejemplo ilustra esto:
using System;
namespace AplicacionCodigoNoSeguro {
class PruebaPuntero {
public unsafe void Intercambiar(int* p, int* q) {
int temp = *p;
*p = *q;
*q = temp;
}
public unsafe static void Main() {
PruebaPuntero p = new PruebaPuntero();
int var1 = 10;
int var2 = 20;
int* x = &var1;
int* y = &var2;
Console.WriteLine("Antes de intercambiar: var1:{0}, var2: {1}", var1, var2);
p.Intercambiar(x, y);
Console.WriteLine("Después de intercambiar: var1:{0}, var2: {1}", var1, var2);
Console.ReadKey();
}
}
}
Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:
Antes de intercambiar: var1: 10, var2: 20 Después de intercambiar: var1: 20, var2: 10
Acceso a elementos de array usando un puntero
En C#, un nombre de array y un puntero a un tipo de dato igual que el del array no son del mismo tipo de variable. Por ejemplo, int *p e int[] p no son del mismo tipo. Puedes incrementar la variable puntero p porque no está fija en memoria, pero la dirección de un array está fija en memoria y no puedes incrementarla.
Por lo tanto, si necesitas acceder a datos de un array usando una variable puntero, como se hace tradicionalmente en C o C++, necesitas fijar el puntero usando la palabra clave fixed.
El siguiente ejemplo demuestra esto:
using System;
namespace AplicacionCodigoNoSeguro {
class PruebaPuntero {
public unsafe static void Main() {
int[] lista = {10, 100, 200};
fixed(int *ptr = lista) /* obtener dirección del array en el puntero */
for (int i = 0; i < 3; i++) {
Console.WriteLine("Dirección de lista[{0}]={1}", i, (int)(ptr + i));
Console.WriteLine("Valor de lista[{0}]={1}", i, *(ptr + i));
}
Console.ReadKey();
}
}
}
Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:
Dirección de lista[0] = 31627168 Valor de lista[0] = 10 Dirección de lista[1] = 31627172 Valor de lista[1] = 100 Dirección de lista[2] = 31627176 Valor de lista[2] = 200
Compilación de código no seguro
Para compilar código no seguro, debes especificar el modificador de línea de comandos /unsafe con el compilador de línea de comandos.
Por ejemplo, para compilar un programa llamado prog1.cs que contiene código no seguro, desde la línea de comandos ejecuta:
csc /unsafe prog1.cs
Si usas Visual Studio IDE, debes habilitar el uso de código no seguro en las propiedades del proyecto:
Abre propiedades del proyecto haciendo doble clic en el nodo de propiedades en el Explorador de soluciones.
Haz clic en la pestaña Compilar.
Selecciona la opción "Permitir código no seguro".
Lenguaje C
- Códigos de Color de Resistencias – Guía Completa para Decodificar Valor, Tolerancia y Estándares E-Series
- Códigos de Color de Cableado Estándar para Circuitos AC y DC – IEC, EE. UU., Reino Unido y Canadá
- Guía Completa de Códigos de Color de Cableado – EE. UU., Europa, Canadá y Más
- Elección entre Data Matrix y Códigos QR: ¿Cuál es Mejor para su Negocio?
- Guía completa de M-Codes para fresadora Haas: Funciones, ajustes y uso
- Guía Completa de Códigos M de Mach3 para Mecanizado CNC
- Dominio Códigos M: Cuestionario Programación CNC
- Domina los Códigos G: Realiza el Cuestionario de Programación CNC
- Dominando punteros en C++: Conceptos, ejemplos y aplicaciones prácticas
- Punteros en C: Guía completa sobre tipos, uso y mejores prácticas
- Dominando punteros en C: Pasos prácticos para programación avanzada