Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Con trỏ (Pointer) trong C# - Unsafe Context

Con trỏ (Pointer) là biến lưu địa chỉ bộ nhớ của biến khác. C# cho phép con trỏ chỉ trong unsafe context (method, type, hoặc block). Dùng cho interop, high-performance, low-level memory manipulation.

Lưu ý: Code unsafe không được verify bởi CLR, có thể gây memory corruption, security vulnerability. Chỉ dùng khi cần thiết.

Cú pháp cơ bản

// Khai báo con trỏ
int* p;        // Con trỏ tới int
double* d;    // Con trỏ tới double
byte* bytes;  // Con trỏ tới byte (thường dùng cho raw memory)

// Lấy địa chỉ (Address-of operator)
int value = 42;
int* ptr = &value;

// Dereference (Indirection operator)
int val = *ptr; // 42
*ptr = 100;       // Thay đổi value qua con trỏ

Ví dụ: Khai báo và sử dụng con trỏ

using System;

class Program
{
    // Unsafe method
    static unsafe void Main()
    {
        int val = 50;
        int* x = &val; // Lấy địa chỉ val
        
        Console.WriteLine($"Data: {val}");
        Console.WriteLine($"Address: {(long)x:X}"); // In địa chỉ hex
        
        // Thay đổi qua con trỏ
        *x = 100;
        Console.WriteLine($"New Data: {val}"); // 100
        
        // Pointer arithmetic
        int[] arr = { 10, 20, 30, 40, 50 };
        fixed (int* p = arr) // Pin array (GC không di chuyển)
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine($"arr[{i}] = {*(p + i)} at address {(long)(p + i):X}");
            }
        }
    }
}

Kết quả

Data: 50
Address: 12345678 (ví dụ)
New Data: 100
arr[0] = 10 at address 12345678
arr[1] = 20 at address 1234567C
arr[2] = 30 at address 12345680
arr[3] = 40 at address 12345684
arr[4] = 50 at address 12345688

Kích thước kiểu con trỏ (sizeof)

  • Trên 32-bit process: 4 bytes
  • Trên 64-bit process: 8 bytes
  • Dùng IntPtr.Size hoặc sizeof(void*) trong unsafe.

Các loại con trỏ

LoạiVí dụMô tả
Primitive pointersint*, double*, char*Kiểu giá trị đơn giản
Void pointervoid*Con trỏ chung, không kiểu, cần cast
Struct pointerPoint*Struct không chứa reference field
Function pointer (C# 9+)delegate*<int, int>Con trỏ hàm managed, dùng cho interop

Fixed Statement - Quan trọng!

Managed objects (array, string, class) có thể bị GC di chuyển. fixed pin (ghim) object trong memory:

string s = "Hello";
fixed (char* p = s) // Pin string
{
    // p trỏ đến char đầu tiên của string
}
// Unpin tự động

Bật Unsafe trong Project

// .csproj
<PropertyGroup>
  <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

Hoặc Properties → Build → "Allow unsafe code".