English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Código Inseguro (Unsafe) do C#

Quando um bloco de código usa insegura ao marcar o modificador, o C# permite o uso de variáveis de ponteiro em funções.Código não seguroou código não gerenciado é aquele que usaPonteiroBloco de código da variável.

Variável de ponteiro

Ponteiro é uma variável cujo valor é o endereço de outra variável, ou seja, o endereço direto da posição de memória. Como outras variáveis ou constantes, você deve declarar o ponteiro antes de usar para armazenar o endereço de outra variável.

A forma geral da declaração de variável de ponteiro é:

type* var-name;

A seguir estão exemplos de declarações de tipos de ponteiros:

ExemploDescrição
int* pp é um ponteiro para um inteiro.
double* pp é um ponteiro para um número double.
float* pp é um ponteiro para um número de ponto flutuante.
int** pp é um ponteiro para um ponteiro de inteiros.
int*[] pp é um array unidimensional de ponteiros para inteiros.
char* pp é um ponteiro para um caractere.
void* pp é um ponteiro para um tipo desconhecido.

Quando vários ponteiros são declarados na mesma declaração, o asterisco * Apenas com tipos básicos, não como prefixo de cada nome de ponteiro. Por exemplo:

int* p1, p2, p3;     // Correto  
int *p1, *p2, *p3;   // Erro

O exemplo a seguir ilustra que no C# foi usado insegura Uso de ponteiros como modificador:

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 for compilado e executado, ele produzirá os seguintes resultados:

Dado é: 20
Endereço é: 99215364

Você também pode não declarar todo o método como código não seguro, basta declarar parte do método como código não seguro. O exemplo a seguir ilustra isso.

Usar ponteiros para recuperar valores de dados

Você pode usar ToString() O método recupera os dados armazenados na posição referenciada pelo variável de ponteiro. O exemplo a seguir ilustra isso:

using System;
namespace UnsafeCodeApplication
{
   class Program
   {
      public static void Main()
      {
         insegura
         {
            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 for compilado e executado, ele produzirá os seguintes resultados:

Dado é: 20
Dado é: 20
Endereço é: 77128984

Passar ponteiros como parâmetros do método

Você pode passar variáveis de ponteiro como parâmetros do método. 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("Before Swap: var1:{0}, var2: {1}1, var2);
         p.swap(x, y);
         Console.WriteLine("After Swap: var1:{0}, var2: {1}1, var2);
         Console.ReadKey();
      }
   }
}

Quando o código acima for compilado e executado, ele produzirá os seguintes resultados:

Before Swap: var1: 10, var2: 20
After Swap: var1: 20, var2: 10

Acessar elementos do array usando ponteiros

Em C#, o nome do array e um ponteiro que aponta para dados do mesmo tipo de dados do array são tipos de variáveis diferentes. Por exemplo, int *p e int[] p são tipos de dados diferentes. Você pode aumentar o ponteiro p, pois ele não é fixo na memória, mas o endereço do array é fixo na memória, então você não pode aumentar o array p.

Portanto, se você precisar usar variáveis de ponteiros para acessar dados de array, pode fazer como geralmente fazemos em C ou C++++ Da mesma forma que foi feito na fixed palavras-chave para fixar ponteiros.

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)
         /* Exibir o endereço do array no ponteiro */
         for ( int i = 0; i < 3; i++)
         {
            Console.WriteLine("Endereço da lista[{0}]={1} + i));
            Console.WriteLine("Valor da lista[{0}]={1} *(ptr + i));
         }
         Console.ReadKey();
      }
   }
}

Quando o código acima for compilado e executado, ele produzirá os seguintes resultados:

Endereço da lista[0] = 31627168
Valor da lista[0] = 10
Endereço da lista[1] = 31627172
Valor da lista[1] = 100
Endereço da lista[2] = 31627176
Valor da lista[2] = 200

Compilar código inseguro

Para compilar código inseguro, você deve alternar para o compilador de linha de comando especificado /insegura Linha de comando.

Por exemplo, para compilar um programa chamado prog que contenha código inseguro1Para compilar um programa .cs que contenha código inseguro, insira o comando na linha de comando:

csc /unsafe prog1.cs

Se você estiver usando o IDE Visual Studio, você precisará ativar o código inseguro nas propriedades do projeto.

Os passos são os seguintes:

  • Se você estiver usando o IDE Visual Studio, você precisará ativar o código inseguro nas propriedades do projeto.Propriedades do Projeto (Project Properties)

  • Clique Construir Aba.

  • Selecione a opção "Permitir código inseguro"。