Dominando Código Unsafe em C#: Guia de Ponteiros e Gerenciamento de Memória
C# permite usar variáveis ponteiro em uma função ou bloco de código quando marcado com o modificador unsafe. O código unsafe ou código não gerenciado é um bloco de código que usa uma variável ponteiro.
Ponteiros
Um ponteiro é uma variável cujo valor é o endereço de outra variável, ou seja, o endereço direto da localização de memória. Semelhante a qualquer variável ou constante, você deve declarar um ponteiro antes de usá-lo para armazenar qualquer endereço de variável.
A forma geral de uma declaração de ponteiro é:
tipo *nome-var;
Seguem declarações de ponteiro válidas:
int *ip; /* ponteiro para um inteiro */ double *dp; /* ponteiro para um double */ float *fp; /* ponteiro para um float */ char *ch /* ponteiro para um character */
O exemplo a seguir ilustra o uso de ponteiros em C#, usando o modificador unsafe:
using System;
namespace UnsafeCodeApplication {
class Program {
static unsafe void Main(string[] args) {
int var = 20;
int* p = &var;
Console.WriteLine("Dado é: {0} ", var);
Console.WriteLine("Endereço é: {0}", (int)p);
Console.ReadKey();
}
}
}
Quando o código acima foi compilado e executado, produz o seguinte resultado:
Dado é: 20 Endereço é: 99215364
Em vez de declarar um método inteiro como unsafe, você também pode declarar uma parte do código como unsafe. O exemplo na seção a seguir mostra isso.
Recuperando o Valor do Dado Usando um Ponteiro
Você pode recuperar o dado armazenado no local referenciado pela variável ponteiro, usando o método ToString(). O exemplo a seguir demonstra isso:
using System;
namespace UnsafeCodeApplication {
class Program {
public static void Main() {
unsafe {
int var = 20;
int* p = &var;
Console.WriteLine("Dado é: {0} " , var);
Console.WriteLine("Dado é: {0} " , p->ToString());
Console.WriteLine("Endereço é: {0} " , (int)p);
}
Console.ReadKey();
}
}
}
Quando o código acima foi compilado e executado, produz o seguinte resultado:
Dado é: 20 Dado é: 20 Endereço é: 77128984
Passando Ponteiros como Parâmetros para Métodos
Você pode passar uma variável ponteiro para um método como parâmetro. O exemplo a seguir ilustra isso:
using System;
namespace UnsafeCodeApplication {
class TestPointer {
public unsafe void swap(int* p, int *q) {
int temp = *p;
*p = *q;
*q = temp;
}
public unsafe static void Main() {
TestPointer p = new TestPointer();
int var1 = 10;
int var2 = 20;
int* x = &var1;
int* y = &var2;
Console.WriteLine("Antes do Swap: var1:{0}, var2: {1}", var1, var2);
p.swap(x, y);
Console.WriteLine("Após Swap: var1:{0}, var2: {1}", var1, var2);
Console.ReadKey();
}
}
}
Quando o código acima é compilado e executado, produz o seguinte resultado:
Antes do Swap: var1: 10, var2: 20 Após Swap: var1: 20, var2: 10
Acessando Elementos de Array Usando um Ponteiro
Em C#, um nome de array e um ponteiro para um tipo de dado igual ao do array, não são o mesmo tipo de variável. Por exemplo, int *p e int[] p, não são o mesmo tipo. Você pode incrementar a variável ponteiro p porque ela não é fixa na memória, mas um endereço de array é fixo na memória, e você não pode incrementá-lo.
Portanto, se você precisar acessar dados de array usando uma variável ponteiro, como fazemos tradicionalmente em C ou C++ (verifique: Ponteiros em C), você precisa fixar o ponteiro usando a palavra-chave fixed.
O exemplo a seguir demonstra isso:
using System;
namespace UnsafeCodeApplication {
class TestPointer {
public unsafe static void Main() {
int[] list = {10, 100, 200};
fixed(int *ptr = list) /* vamos ter endereço do array no ponteiro */
for ( int i = 0; i < 3; i++) {
Console.WriteLine("Endereço de list[{0}]={1}",i,(int)(ptr + i));
Console.WriteLine("Valor de list[{0}]={1}", i, *(ptr + i));
}
Console.ReadKey();
}
}
}
Quando o código acima foi compilado e executado, produz o seguinte resultado:
Endereço de list[0] = 31627168 Valor de list[0] = 10 Endereço de list[1] = 31627172 Valor de list[1] = 100 Endereço de list[2] = 31627176 Valor de list[2] = 200
Compilando Código Unsafe
Para compilar código unsafe, você deve especificar a opção de linha de comando /unsafe com o compilador de linha de comando.
Por exemplo, para compilar um programa chamado prog1.cs contendo código unsafe, da linha de comando, dê o comando:
csc /unsafe prog1.cs
Se você estiver usando o Visual Studio IDE, precisará habilitar o uso de código unsafe nas propriedades do projeto.
Para fazer isso:
Abra propriedades do projeto clicando duas vezes no nó properties no Solution Explorer.
Clique na aba Build.
Selecione a opção "Allow unsafe code" (Permitir código unsafe).
Linguagem C
- Códigos de Cores de Resistores – Guia Completo para Decodificar Valor, Tolerância e Padrões E-Series
- Códigos de Cores de Fiação Padrão para Circuitos CA e CC – IEC, EUA, Reino Unido e Canadá
- Dominando Ponteiros em C++: Conceitos, Exemplos e Aplicações Práticas
- Ponteiros em C: Guia Completo sobre Tipos, Uso e Melhores Práticas
- Dominando Ponteiros em C: Passos Práticos para Programação Avançada
- Escolhendo entre Data Matrix e QR Codes: Qual é Melhor para seu Negócio
- Guia Completo de M-Codes Haas Mill: Funções, Configurações e Uso
- Guia Completo dos M-Codes Mach3 para Usinagem CNC
- Domínio de Códigos M: Quiz de Programação CNC
- Domine Códigos G: Faça o Quiz de Programação CNC