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.Sizehoặcsizeof(void*)trong unsafe.
Các loại con trỏ
| Loại | Ví dụ | Mô tả |
|---|---|---|
| Primitive pointers | int*, double*, char* | Kiểu giá trị đơn giản |
| Void pointer | void* | Con trỏ chung, không kiểu, cần cast |
| Struct pointer | Point* | 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".