ภาพรวม
ความแตกต่างมาจาก **Type System** ของภาษา:
- C:
void* Implicitly Convertible to Any Pointer Type - C++:
void* NOT** Implicitly Convertible to Other Pointer Types (Strong Typing)
ใน C (Implicit Conversion)
// C Code - Valid
#include
int main() {
int* ptr = malloc(10 * sizeof(int)); // No Cast Needed!
// void* → int* Implicit Conversion Allowed in C
return 0;
}
ใน C++ (Explicit Cast Required)
// C++ Code - Error without Cast
#include
int main() {
// int* ptr = malloc(10 * sizeof(int)); // ❌ Error: invalid conversion from 'void*' to 'int*'
int* ptr = static_cast(malloc(10 * sizeof(int))); // ✅ OK: Explicit Cast
// หรือ C-Style Cast
int* ptr2 = (int*)malloc(10 * sizeof(int)); // ✅ OK (แต่ไม่แนะนำใน C++)
return 0;
}
ทำไม C++ จึงเข้มงวดกว่า?
- Type Safety: ป้องกัน Bug จากการ Cast ผิด Type
- Constructor/Destructor:
mallocไม่เรียก Constructor → Object ไม่ได้ Initialize Properly - Overloading:
newสามารถ Overload ได้mallocไม่ได้ - Alignment:
newรับประกัน Alignment ถูกต้องสำหรับ Type
Best Practice ใน C++: อย่าใช้ malloc/free
✅ ใช้ new/delete หรือ Smart Pointers/Containers แทน
1. new/delete (Basic)
int* ptr = new int[10]; // Array
int* ptr2 = new int(42); // Single with Value
// ต้องจับคู่:
delete[] ptr; // Array
delete ptr2; // Single
2. Smart Pointers (Modern C++ - แนะนำ)
#include
// Unique Ownership
auto uptr = std::make_unique(10); // Array (C++17)
auto uptr2 = std::make_unique(42); // Single
// Shared Ownership
auto sptr = std::make_shared(42);
auto sptr2 = std::make_shared(10); // C++20: make_shared for arrays
3. Containers (Best for Arrays)
#include
#include
// Dynamic Array
std::vector vec(10); // Managed, Resizable, Safe
// Fixed Array
std::array arr; // Stack, Fixed Size, Safe
เมื่อไหร่ต้องใช้ malloc ใน C++? (Rare Cases)
- Interfacing กับ C Libraries ที่ต้องการ malloc/free
- Custom Memory Allocators (Memory Pools, Arena Allocators)
- Placement New ใช้กับ Pre-allocated Buffer
- Shared Memory / mmap Regions
Placement New Example (Advanced)
#include // Placement New
#include // malloc/free
class MyClass {
int data;
public:
MyClass(int d) : data(d) {}
~MyClass() {}
};
int main() {
// Allocate Raw Memory
void* raw = malloc(sizeof(MyClass));
// Construct Object in Raw Memory (Placement New)
MyClass* obj = new (raw) MyClass(42);
// Use Object
// ...
// Explicit Destructor Call
obj->~MyClass();
// Free Raw Memory
free(raw);
return 0;
}
ตารางเปรียบเทียบ malloc vs new
| Feature | malloc/free | new/delete | Smart Pointers/Containers |
|---|---|---|---|
| Constructor Call | ❌ No | ✅ Yes | ✅ Yes |
| Destructor Call | ❌ No | ✅ Yes | ✅ Yes (Auto) |
| Type Safety | ❌ void* | ✅ Typed | ✅ Typed |
| Failure Handling | Returns NULL | Throws bad_alloc | Throws/Exceptions |
| Overloadable | ❌ No | ✅ Yes | N/A |
| Alignment | Max Alignment | Type Alignment | Type Alignment |
| Memory Management | Manual | Manual | ✅ Automatic (RAII) |
| Exception Safety | Manual | Manual | ✅ Guaranteed |
สรุป
- C:
void*Convert Implicitly → ไม่ต้อง Cast - C++:
void*ไม่ Convert Implicitly → ต้อง Cast (แต่ไม่ควรใช้ malloc) - Modern C++: ใช้
std::vector,std::array,std::make_unique,std::make_shared - ถ้าบังคับต้อง malloc ใน C++: ใช้
static_cast<T*>(malloc(...))