Pointer คือตัวแปรที่เก็บ ที่อยู่หน่วยความจำ (Memory Address) ของตัวแปรอีกตัวหนึ่ง ใน C# Pointer ใช้ได้เฉพาะในบริบท unsafe code เท่านั้น เนื่องจาก C# เป็น Managed Language ที่ Garbage Collector จัดการหน่วยความจำให้อัตโนมัติ
Syntax การประกาศ Pointer
type* variableName;
ตัวอย่างการประกาศ
int* ip; // Pointer to integer
double* dp; // Pointer to double
char* cp; // Pointer to char
int** ipp; // Pointer to pointer
Unsafe Context - ข้อกำหนด
- ต้องคอมไพล์ด้วย flag
/unsafe(Project Properties → Build → Allow unsafe code) - โค้ดที่ใช้ pointer ต้องอยู่ในบล็อก
unsafeหรือเมธอดที่มี modifierunsafe - ใช้ได้กับ Unmanaged Types เท่านั้น (primitive types, enum, struct ที่ไม่มี reference fields)
ตัวอย่างการใช้งาน Pointer
using System;
namespace PointerDemo {
class Program {
static unsafe void Main(string[] args) {
int var = 20;
int* p = &var; // & = Address-of operator
Console.WriteLine("Data is: {0}", var); // 20
Console.WriteLine("Address is: {0}", (int)p); // Memory address
// Dereference - เข้าถึงค่าผ่าน pointer
Console.WriteLine("Value via pointer: {0}", *p); // 20
// แก้ไขค่าผ่าน pointer
*p = 30;
Console.WriteLine("New value: {0}", var); // 30
Console.ReadKey();
}
}
}
ผลลัพธ์
Data is: 20
Address is: 12345678 (ตัวอย่าง)
Value via pointer: 20
New value: 30
Operators สำคัญกับ Pointer
| Operator | ชื่อ | คำอธิบาย |
|---|---|---|
& |
Address-of | lấyที่อยู่ของตัวแปร |
* |
Dereference / Indirection | เข้าถึงค่าที่ address นั้นๆ |
-> |
Member Access | เข้าถึงสมาชิกของ struct ผ่าน pointer (p->Member) |
[] |
Pointer Indexing | เข้าถึงแบบ Array (p[i] เทียบเท่า *(p+i)) |
Pointer Arithmetic
unsafe {
int[] arr = { 10, 20, 30, 40, 50 };
fixed (int* p = arr) { // pin array ในหน่วยความจำ
for (int i = 0; i < 5; i++) {
Console.WriteLine(*(p + i)); // 10, 20, 30, 40, 50
}
}
}
Fixed Statement - ป้องกัน GC ย้ายหน่วยความจำ
Garbage Collector อาจย้าย Object ใน Heap ได้ ต้องใช้ fixed เพื่อ "Pin" Object ไว้ชั่วคราว
unsafe {
string s = "Hello";
fixed (char* p = s) {
// p ชี้ไปที่ char แรกของ string
for (int i = 0; i < s.Length; i++) {
Console.Write(p[i]);
}
}
// s ถูก unpinned อัตโนมัติเมื่อออกจากบล็อก fixed
}
Stackalloc - จัดสรรหน่วยความจำบน Stack
unsafe {
int* arr = stackalloc int[100]; // ไม่ต้อง fixed, ฟรีอัตโนมัติเมื่อจบ scope
for (int i = 0; i < 100; i++) arr[i] = i * i;
}
เมื่อไหร่ควรใช้ Pointer?
- Interop กับ Unmanaged Code (C/C++ DLL, Win32 API, COM)
- Performance-critical code (Image processing, Cryptography, Game engines)
- Memory-mapped files, Hardware communication
⚠️ ข้อควรระวัง
- Pointer ทำให้ Code ไม่ปลอดภัย (Type Safety, Memory Safety)
- GC ไม่สามารถติดตาม Memory ผ่าน Pointer ได้
- Buffer Overrun, Dangling Pointer, Memory Leak เป็นความเสี่ยง
- ใช้
Span<T>,Memory<T>แทนได้ในหลายกรณี (Safe, Modern)