Variable Length Array (VLA) คืออะไร?
Array ที่ขนาดกำหนดได้ **ตอน Runtime** (ไม่ใช่ Compile-time Constant)
ในภาษา C (C99 Standard)
- **รองรับ VLA อย่างเป็นทางการ** (Mandatory ใน C99, Optional ใน C11+)
- จอง Memory บน **Stack**
- ขนาดต้องไม่เกิน Stack Limit (~1-8 MB)
void func(int n) {
int arr[n]; // VLA - OK ใน C99
// ...
}
ในภาษา C++
- ไม่รองรับ VLA ใน Standard** (C++11, C++14, C++17, C++20, C++23)
- GCC/Clang รองรับเป็น **Extension** (
-pedanticจะเตือน) - MSVC ไม่รองรับเลย
- ทางเลือกใน C++:
std::vector,std::unique_ptr,new[]
ตัวอย่าง C: VLA พื้นฐาน
#include
#include
void make_arr(int n) {
int array[n]; // VLA
for (int i = 0; i < n; i++)
array[i] = i * i;
for (int i = 0; i < n; i++)
printf("%d ", array[i]);
printf("\n");
}
int main() {
make_arr(10);
return 0;
}
ตัวอย่างขั้นสูง: Flexible Array Member (C99)
#include
#include
#include
struct Employee {
int id;
int name_len;
char name[]; // Flexible Array Member (ต้องเป็นสมาชิกตัวสุดท้าย)
};
struct Employee *make_emp(int id, const char *name) {
int len = strlen(name);
struct Employee *e = malloc(sizeof(struct Employee) + len + 1);
e->id = id;
e->name_len = len;
strcpy(e->name, name);
return e;
}
void print_emp(struct Employee *e) {
printf("ID: %d, Name: %s, Len: %d, Size: %zu\n",
e->id, e->name, e->name_len,
sizeof(struct Employee) + e->name_len + 1);
}
int main() {
struct Employee *e1 = make_emp(101, "Jayanta Das");
struct Employee *e2 = make_emp(201, "Tushar Dey");
print_emp(e1);
print_emp(e2);
printf("Struct size (no FAM): %zu\n", sizeof(struct Employee));
printf("Pointer size: %zu\n", sizeof(e1));
free(e1); free(e2);
return 0;
}
ผลลัพธ์:
ID: 101, Name: Jayanta Das, Len: 11, Size: 23
ID: 201, Name: Tushar Dey, Len: 10, Size: 22
Struct size (no FAM): 12
Pointer size: 8
VLA vs Dynamic Allocation (malloc)
| คุณสมบัติ | VLA (Stack) | malloc (Heap) |
|---|---|---|
| Lifetime | Scope ของ Block | Manual (free) |
| Size Limit | Stack Size (~MB) | Heap Size (~GB) |
| Speed | เร็วมาก (Pointer Bump) | ช้ากว่า (System Call) |
| Failure Handling | Stack Overflow (Crash) | คืน NULL (Handle ได้) |
| Portability | C99 Only, Optional C11+ | ทุก Version, ทุก Platform |
Best Practice
- ใช้ VLA สำหรับ **Array เล็ก-ปานกลาง** ขนาดรู้ได้ตอน Run
- ใช้
mallocสำหรับ **Array ใหญ่** หรือ **Lifetime ยาวกว่า Function** - ใน C++ ใช้
std::vectorเสมอ - หลีกเลี่ยง VLA ใน Critical Systems (Stack Overflow Risk)