Skip to content
LIVE FEED

BlogTổng hợp các Method/Hàm chuyên dụng, phổ biến trong C/C++

Tổng hợp các Method/Hàm chuyên dụng, phổ biến trong C/C++

Tài liệu liệt kê các hàm/method thường gặp nhất khi lập trình C/C++, kèm giải thích công dụng, ví dụ dùng, và lưu ý an toàn (đặc biệt quan trọng khi làm embedded/viễn thông/an ninh mạng — xem thêm file nguyen-tac-lap-trinh-C-CPP.md).

Ký hiệu: 🔴 = nguy hiểm/nên tránh hoặc cần cẩn trọng đặc biệt · 🟢 = khuyến nghị dùng thay thế.


Mục lục

  1. Quản lý bộ nhớ
  2. Chuỗi ký tự (String)
  3. Con trỏ thông minh (Smart Pointer) — C++
  4. STL Container phổ biến
  5. STL Algorithm phổ biến
  6. Move semantics & Perfect forwarding
  7. Vào/Ra dữ liệu (I/O)
  8. Đa luồng (Concurrency)
  9. Xử lý số & Bit
  10. Mạng, Byte order & Serialize
  11. Bảo mật / Crypto
  12. Kiểm tra lúc biên dịch & Debug
  13. Bảng tra nhanh: “Đừng dùng cái này — dùng cái kia”

1. Quản lý bộ nhớ

Hàm/MethodHeaderCông dụng
malloc(size_t)<cstdlib>Cấp phát vùng nhớ thô size byte, không khởi tạo giá trị, trả về void* (cần cast trong C++). Trả NULL nếu thất bại — luôn phải kiểm tra.
calloc(n, size)<cstdlib>Giống malloc nhưng cấp phát cho n phần tử và tự động khởi tạo về 0. An toàn hơn malloc khi cần buffer sạch.
realloc(ptr, size)<cstdlib>Thay đổi kích thước vùng nhớ đã cấp phát. 🔴 Lưu ý: nếu thất bại trả NULL nhưng con trỏ cũ vẫn còn — không gán đè trực tiếp ptr = realloc(ptr, ...) vì sẽ leak nếu thất bại.
free(ptr)<cstdlib>Giải phóng vùng nhớ do malloc/calloc/realloc cấp. 🔴 Gọi free hai lần (double-free) hoặc dùng con trỏ sau khi free (use-after-free) là UB nghiêm trọng, thường bị khai thác bảo mật.
new / new[](từ khóa)Cấp phát bộ nhớ và gọi constructor. Ném std::bad_alloc nếu thất bại (khác malloc trả NULL).
delete / delete[](từ khóa)Gọi destructor và giải phóng bộ nhớ. 🔴 Phải khớp: new đi với delete, new[] đi với delete[] — lẫn lộn là UB.
new(std::nothrow)<new>Biến thể của new không ném exception mà trả nullptr khi thất bại — dùng khi code không cho phép exception (embedded).
std::make_unique<T>(args...) 🟢<memory>Cách khuyến nghị để tạo unique_ptr — an toàn hơn new trần vì tránh leak khi có exception giữa new và gán vào smart pointer.
std::make_shared<T>(args...) 🟢<memory>Tương tự cho shared_ptr, đồng thời tối ưu hơn (gộp một lần cấp phát cho object + control block thay vì hai lần).
std::allocator<T><memory>Bộ cấp phát bộ nhớ chuẩn hóa dùng bên trong container STL — dùng khi viết container tùy chỉnh hoặc cần custom allocator (phổ biến trong embedded để dùng memory pool).
placement new — new(ptr) T(args)<new>Gọi constructor tại một vùng nhớ đã cấp phát sẵn (không cấp phát mới). Dùng nhiều trong embedded/memory pool khi cần kiểm soát chính xác vị trí object trong bộ nhớ.
memcpy(dst, src, n)<cstring>Sao chép n byte từ src sang dst. 🔴 Vùng nhớ không được chồng lấn (overlap) — nếu chồng lấn phải dùng memmove.
memmove(dst, src, n) 🟢<cstring>Giống memcpy nhưng an toàn khi vùng nhớ nguồn/đích chồng lấn nhau.
memset(ptr, value, n)<cstring>Gán n byte tại ptr bằng giá trị value (thường dùng để zero-hóa buffer). 🔴 Không dùng để xóa dữ liệu bí mật — compiler có thể tối ưu bỏ qua nếu biến không được đọc lại sau đó (dùng explicit_bzero/memset_s thay thế).
memcmp(a, b, n)<cstring>So sánh n byte đầu của hai vùng nhớ. 🔴 Không dùng để so sánh dữ liệu bảo mật (mật khẩu, MAC, token) vì dừng sớm khi gặp byte khác → lộ thông tin qua thời gian xử lý (timing attack). Dùng hàm constant-time thay thế (xem Mục 11).
// Ví dụ đúng cách dùng realloc an toàn
void* new_ptr = realloc(old_ptr, new_size);
if (new_ptr == NULL) {
    // xử lý lỗi, old_ptr vẫn còn hợp lệ, có thể free nó
    free(old_ptr);
    return -1;
}
old_ptr = new_ptr; // chỉ gán khi chắc chắn thành công

2. Chuỗi ký tự (String)

2.1. Hàm C-style (từ <cstring>) — cẩn trọng cao độ

HàmCông dụngMức độ an toàn
strcpy(dst, src)Sao chép chuỗi🔴 Cấm dùng — không kiểm tra biên, nguyên nhân kinh điển của buffer overflow
strcat(dst, src)Nối chuỗi🔴 Cấm dùng — cùng lý do trên
sprintf(buf, fmt, ...)Format chuỗi vào buffer🔴 Cấm dùng — không giới hạn kích thước ghi
gets(buf)Đọc dòng từ input🔴 Đã bị loại bỏ khỏi chuẩn C11 — tuyệt đối không dùng
strncpy(dst, src, n)Sao chép tối đa n ký tự⚠️ An toàn hơn nhưng không tự động thêm \0 nếu src dài hơn n — dễ gây lỗi nếu quên tự thêm
snprintf(buf, size, fmt, ...) 🟢Format chuỗi có giới hạn kích thướcAn toàn — luôn dùng thay cho sprintf
strlen(s)Đếm độ dài chuỗi (không tính \0)An toàn nếu chuỗi đã kết thúc đúng bằng \0; 🔴 nếu buffer không có \0 sẽ đọc tràn ngoài biên
strncat(dst, src, n)Nối tối đa n ký tựAn toàn hơn strcat nhưng vẫn dễ nhầm kích thước buffer đích
strtol/strtoul/strtodChuyển chuỗi sang số nguyên/thựcAn toàn hơn atoi/atof vì có báo lỗi qua con trỏ endptr
atoi/atofChuyển chuỗi sang số⚠️ Không báo lỗi khi chuỗi không hợp lệ (trả về 0) — không nên dùng khi cần validate input

2.2. C++ String — khuyến nghị dùng thay thế

MethodCông dụng
std::string 🟢Chuỗi tự quản lý bộ nhớ, tự động resize, an toàn hơn C-string rất nhiều. Nên dùng mặc định trừ khi có lý do đặc biệt (embedded hạn chế heap).
.substr(pos, len)Lấy chuỗi con
.find(str)Tìm vị trí xuất hiện, trả std::string::npos nếu không tìm thấy
.append() / operator+=Nối chuỗi, tự quản lý bộ nhớ
.c_str()Lấy con trỏ C-string (const char*) để tương tác với API C
std::string_view 🟢 (C++17)“Nhìn” vào một chuỗi đã tồn tại không copy dữ liệu — cực kỳ hiệu quả khi chỉ cần đọc, không cần sở hữu chuỗi. 🔴 Không giữ string_view lâu hơn vòng đời chuỗi gốc (dangling).
std::to_string(n)Chuyển số sang std::string
std::stoi/stol/stodChuyển chuỗi sang số, ném exception nếu không hợp lệ (khác atoi)
// Không tốt
char buf[64];
sprintf(buf, "value=%d", x); // có thể tràn nếu format string dài

// Tốt
char buf[64];
snprintf(buf, sizeof(buf), "value=%d", x); // luôn an toàn, tự cắt bớt nếu quá dài

// C++ hiện đại
std::string s = "value=" + std::to_string(x);

3. Con trỏ thông minh (Smart Pointer) — C++

MethodCông dụng
std::unique_ptr<T>Sở hữu duy nhất một object, tự giải phóng khi ra khỏi scope. Không copy được, chỉ move (std::move). Chi phí runtime gần như bằng 0 so với con trỏ thô.
.get()Lấy con trỏ thô bên trong (để tương tác API cũ) — không tự ý delete nó, quyền sở hữu vẫn thuộc unique_ptr.
.release()Trả quyền sở hữu con trỏ ra ngoài, unique_ptr không còn quản lý nó nữa (người gọi phải tự delete sau này).
.reset(ptr)Giải phóng object hiện tại (nếu có) và nhận quản lý object mới.
std::shared_ptr<T>Nhiều nơi cùng sở hữu một object, tự đếm tham chiếu (reference counting), giải phóng khi tham chiếu cuối cùng biến mất. Chi phí cao hơn unique_ptr (atomic increment/decrement).
.use_count()Số lượng shared_ptr đang cùng trỏ tới object — hữu ích khi debug leak.
std::weak_ptr<T>“Quan sát” một shared_ptr mà không tăng reference count — dùng để phá vòng lặp tham chiếu (circular reference) giữa hai shared_ptr trỏ lẫn nhau, tránh leak.
.lock()Từ weak_ptr, thử lấy shared_ptr hợp lệ — trả về rỗng nếu object đã bị hủy.
std::enable_shared_from_this<T>Cho phép một object tự tạo shared_ptr trỏ đến chính nó một cách an toàn (dùng trong callback/async).
// Ví dụ vòng lặp tham chiếu — cần weak_ptr để tránh leak
struct Node {
    std::shared_ptr<Node> next;
    std::weak_ptr<Node> prev; // dùng weak_ptr để phá vòng lặp
};

4. STL Container phổ biến

ContainerĐặc điểmKhi nào dùng
std::vector<T>Mảng động, liên tục trong bộ nhớ (cache-friendly)Mặc định nên dùng khi cần danh sách có thứ tự
std::array<T, N>Mảng kích thước cố định biết trước lúc compileEmbedded/real-time — không cấp phát động
std::deque<T>Mảng động hai đầu, thêm/xóa đầu-cuối nhanhKhi cần push/pop cả hai đầu
std::list<T>Danh sách liên kết đôiKhi cần chèn/xóa giữa danh sách thường xuyên, không cần truy cập ngẫu nhiên
std::map<K,V>Cây nhị phân cân bằng (thường Red-Black tree), tự sắp xếp theo keyKhi cần key có thứ tự, độ phức tạp O(log n)
std::unordered_map<K,V>Bảng băm (hash table)Khi cần tra cứu nhanh O(1) trung bình, không cần thứ tự
std::set<T> / std::unordered_set<T>Tương tự map nhưng chỉ lưu key (không value)Khi cần tập hợp không trùng lặp
std::span<T> (C++20) 🟢“Nhìn” vào một mảng/vùng nhớ liên tục, mang theo độ dài, không sở hữu dữ liệuTruyền buffer an toàn giữa các hàm mà không copy — rất hữu ích khi parse dữ liệu mạng
std::optional<T> (C++17) 🟢Biểu diễn giá trị “có thể không tồn tại”Thay thế con trỏ nullptr hoặc giá trị sentinel để báo “không có kết quả”
std::variant<T1,T2,...> (C++17)Union kiểu an toàn (type-safe union)Khi một biến có thể là một trong nhiều kiểu khác nhau
std::pair / std::tupleGom nhóm nhiều giá trịTrả về nhiều giá trị từ một hàm

Method phổ biến trên container:

MethodCông dụng
.push_back(x)Thêm phần tử vào cuối
.emplace_back(args...) 🟢Xây dựng object trực tiếp tại chỗ trong container thay vì tạo object rồi copy/move vào — hiệu quả hơn push_back
.reserve(n)Cấp phát trước bộ nhớ cho n phần tử, tránh phải cấp phát lại nhiều lần khi thêm dần
.size() / .empty()Số lượng phần tử / kiểm tra rỗng
.at(i) 🟢Truy cập phần tử có kiểm tra biên, ném std::out_of_range nếu sai — an toàn hơn operator[]
operator[]Truy cập nhanh, không kiểm tra biên — UB nếu truy cập sai chỉ số
.find(key)Tìm phần tử theo key (map/set), trả về iterator, so với .end() để biết có tìm thấy không
.erase(it)Xóa phần tử tại vị trí iterator
.clear()Xóa toàn bộ phần tử

5. STL Algorithm phổ biến

Header <algorithm> — các hàm thao tác trên container thông qua iterator, giúp code ngắn gọn và ít lỗi hơn viết vòng lặp tay.

HàmCông dụng
std::sort(begin, end)Sắp xếp, độ phức tạp trung bình O(n log n)
std::find(begin, end, value)Tìm phần tử đầu tiên bằng value, trả về iterator (so với end() để biết có tìm thấy không)
std::find_if(begin, end, pred)Tìm phần tử đầu tiên thỏa điều kiện (lambda/hàm)
std::count(begin, end, value)Đếm số lần xuất hiện
std::for_each(begin, end, fn)Áp dụng hàm fn cho từng phần tử
std::transform(begin, end, out, fn)Áp dụng hàm biến đổi và ghi kết quả ra container khác
std::accumulate(begin, end, init)Tính tổng (hoặc gộp theo hàm tùy chỉnh) — header <numeric>
std::all_of / any_of / none_ofKiểm tra điều kiện cho toàn bộ / một phần / không phần tử nào
std::unique(begin, end)Loại bỏ phần tử trùng liên tiếp (cần sort trước nếu muốn loại trùng toàn bộ)
std::remove_if(begin, end, pred)“Dịch chuyển” phần tử không thỏa điều kiện lên đầu (không thực sự xóa khỏi container — cần kết hợp .erase(), gọi là erase-remove idiom)
std::copy / std::move (algorithm)Sao chép / di chuyển phần tử giữa các container
std::clamp(v, lo, hi) (C++17)Giới hạn giá trị trong khoảng [lo, hi]
std::min / std::max / std::min_element / std::max_elementTìm giá trị nhỏ nhất/lớn nhất
// Erase-remove idiom — xóa toàn bộ phần tử thỏa điều kiện
std::vector<int> v = {1, 2, 3, 4, 5};
v.erase(std::remove_if(v.begin(), v.end(),
                        [](int x) { return x % 2 == 0; }),
        v.end());
// v = {1, 3, 5}

6. Move semantics & Perfect forwarding

Method/Từ khóaCông dụng
std::move(x)Không di chuyển gì cả — chỉ là ép kiểu x thành rvalue reference, báo cho compiler biết “có thể lấy cắp tài nguyên của biến này”. Sau khi move, biến gốc ở trạng thái “hợp lệ nhưng không xác định giá trị” — không nên dùng lại.
std::forward<T>(x)Dùng trong template để “chuyển tiếp” đúng loại tham chiếu (lvalue/rvalue) tới hàm khác — nền tảng của perfect forwarding.
Move constructor T(T&& other)Constructor “lấy cắp” tài nguyên từ object tạm thời thay vì copy — hiệu quả hơn nhiều với object lớn (vector, string…).
RVO/NRVO (Return Value Optimization)Compiler tự động tối ưu bỏ qua việc copy/move khi trả về object từ hàm — không cần viết return std::move(local_var) (thậm chí có thể làm mất tối ưu này).
std::vector<int> big_vector = createLargeVector();
std::vector<int> another = std::move(big_vector);
// big_vector giờ ở trạng thái rỗng/không xác định, đừng dùng lại nó

7. Vào/Ra dữ liệu (I/O)

MethodHeaderCông dụng
printf/scanf họ hàm<cstdio>I/O kiểu C, nhanh nhưng không type-safe — dễ lỗi format string (🔴 nguy cơ bảo mật nếu format string lấy từ input người dùng — “format string vulnerability”)
std::cout / std::cin<iostream>I/O kiểu C++, type-safe hơn nhưng chậm hơn printf nếu không tắt sync với C stdio
std::ifstream / std::ofstream<fstream>Đọc/ghi file, tự động quản lý tài nguyên theo RAII (đóng file khi ra khỏi scope)
std::stringstream<sstream>Parse/format chuỗi qua giao diện stream — tiện khi tách token từ chuỗi
std::ios::sync_with_stdio(false)<iostream>Tắt đồng bộ giữa iostream và stdio, tăng tốc I/O đáng kể khi không trộn printf và cout

🔴 Lưu ý bảo mật: không bao giờ dùng dữ liệu từ input làm format string trực tiếp:

// SAI — format string vulnerability, kẻ tấn công có thể đọc/ghi bộ nhớ tùy ý qua %n, %x...
printf(user_input);

// ĐÚNG
printf("%s", user_input);

8. Đa luồng (Concurrency)

MethodHeaderCông dụng
std::thread<thread>Tạo và quản lý một luồng thực thi mới
.join() Đợi thread kết thúc trước khi tiếp tục — bắt buộc gọi join() hoặc detach() trước khi thread object bị hủy, nếu không chương trình sẽ gọi std::terminate()
.detach() Cho thread chạy độc lập, không cần chờ — cẩn trọng vì mất khả năng kiểm soát vòng đời
std::mutex<mutex>Khóa loại trừ (mutual exclusion) để bảo vệ dữ liệu chia sẻ giữa các thread
std::lock_guard<std::mutex> 🟢<mutex>RAII cho mutex — tự động lock() khi tạo, tự động unlock() khi ra khỏi scope. Nên dùng thay vì lock()/unlock() thủ công để tránh quên unlock khi có exception.
std::unique_lock<std::mutex><mutex>Giống lock_guard nhưng linh hoạt hơn (có thể unlock/lock lại giữa chừng, dùng với condition_variable)
std::lock(m1, m2, ...)<mutex>Khóa nhiều mutex cùng lúc theo cách tránh deadlock (deadlock-avoidance algorithm)
std::atomic<T><atomic>Biến thao tác nguyên tử (atomic) không cần mutex — dùng cho kiểu dữ liệu đơn giản (int, bool, con trỏ) cần đọc/ghi an toàn giữa các thread với chi phí thấp hơn mutex
std::condition_variable<condition_variable>Cơ chế cho một thread “chờ” đến khi có tín hiệu từ thread khác (producer-consumer pattern)
std::async / std::future<future>Chạy hàm bất đồng bộ và lấy kết quả trả về sau (không cần tự quản lý thread thủ công)
std::call_once<mutex>Đảm bảo một đoạn code chỉ chạy đúng một lần dù được gọi từ nhiều thread — dùng cho khởi tạo singleton an toàn
std::mutex mtx;
int shared_counter = 0;

void increment() {
    std::lock_guard<std::mutex> lock(mtx); // tự động unlock khi hàm kết thúc
    ++shared_counter;
}

9. Xử lý số & Bit

Hàm/Toán tửHeaderCông dụng
<< / >> / & / | / ^ / ~(toán tử)Dịch bit trái/phải, AND, OR, XOR, NOT — dùng nhiều khi thao tác thanh ghi phần cứng, cờ trạng thái (flag), giao thức nhị phân
std::bitset<N><bitset>Biểu diễn và thao tác chuỗi bit có kích thước cố định, tiện hơn thao tác bit thủ công trên số nguyên
std::numeric_limits<T>::max()/min()<limits>Lấy giá trị lớn nhất/nhỏ nhất của kiểu số — nên dùng thay vì hardcode (ví dụ tránh viết tay 2147483647)
std::abs / std::round / std::floor / std::ceil<cmath>Các hàm toán học cơ bản
std::gcd / std::lcm (C++17)<numeric>Ước chung lớn nhất / bội chung nhỏ nhất
__builtin_popcount (GCC/Clang)(built-in)Đếm số bit 1 trong một số — tối ưu bằng lệnh CPU chuyên dụng nếu phần cứng hỗ trợ
std::countl_zero / std::countr_zero (C++20)<bit>Đếm số bit 0 ở đầu/cuối — thay thế portable cho các hàm __builtin_* của compiler cụ thể

10. Mạng, Byte order & Serialize

HàmHeaderCông dụng
htons(x) / ntohs(x)<arpa/inet.h> (POSIX)Chuyển đổi số 16-bit giữa thứ tự byte host (máy tính đang chạy) và network (chuẩn big-endian dùng trong giao thức mạng)
htonl(x) / ntohl(x)<arpa/inet.h>Tương tự nhưng cho số 32-bit
inet_pton() / inet_ntop()<arpa/inet.h>Chuyển đổi giữa địa chỉ IP dạng chuỗi ("192.168.1.1") và dạng nhị phân — an toàn hơn hàm cũ inet_addr/inet_ntoa (hỗ trợ cả IPv6, thread-safe)
memcpy (xem Mục 1)<cstring>Cách an toàn để đọc/ghi dữ liệu vào buffer mạng, tránh vi phạm alignment/strict aliasing
std::span<std::byte> (C++20)<span>Biểu diễn buffer thô có kèm độ dài khi truyền giữa các hàm parse — an toàn hơn con trỏ + độ dài rời rạc
// Ví dụ đọc một trường 16-bit từ gói tin nhận qua mạng
uint16_t length_network_order;
std::memcpy(&length_network_order, buffer + offset, sizeof(length_network_order));
uint16_t length = ntohs(length_network_order); // chuyển về thứ tự byte của máy hiện tại

11. Bảo mật / Crypto

HàmNguồnCông dụng
explicit_bzero(ptr, n) (glibc/BSD) hoặc memset_s (C11 Annex K) Xóa vùng nhớ chứa dữ liệu nhạy cảm mà không bị compiler tối ưu bỏ qua — dùng thay memset khi xóa khóa/mật khẩu khỏi bộ nhớ
CRYPTO_memcmp() (OpenSSL)OpenSSLSo sánh hai chuỗi byte với thời gian không đổi (constant-time), chống timing attack — dùng khi so sánh MAC, token, hash
RAND_bytes() (OpenSSL)OpenSSLSinh số ngẫu nhiên an toàn về mật mã (CSPRNG) — dùng cho khóa, nonce, salt. Không dùng rand() cho mục đích này vì dễ đoán được
EVP_* API (OpenSSL)OpenSSLBộ API thống nhất cho mã hóa đối xứng/bất đối xứng, hash, HMAC — nên dùng thay vì gọi trực tiếp các hàm thuật toán cụ thể (linh hoạt đổi thuật toán sau này)
SHA256()/SHA3() họ hàm hashOpenSSL/mbedTLSTính hash — dùng để kiểm tra toàn vẹn dữ liệu, không dùng để lưu mật khẩu trực tiếp (cần thuật toán chuyên cho mật khẩu như bcrypt/Argon2 có “salt” và “cost factor”)
getrandom() (Linux syscall)<sys/random.h>Lấy số ngẫu nhiên trực tiếp từ kernel CSPRNG — an toàn hơn đọc /dev/urandom thủ công trong một số tình huống

🔴 Nhắc lại nguyên tắc quan trọng nhất: không tự viết thuật toán mã hóa, luôn dùng thư viện đã kiểm định (OpenSSL, mbedTLS, wolfSSL cho embedded).


12. Kiểm tra lúc biên dịch & Debug

Method/Từ khóaCông dụng
static_assert(condition, "message") 🟢Kiểm tra điều kiện ngay lúc biên dịch, báo lỗi build nếu sai — dùng để đảm bảo sizeof(struct) đúng như mong đợi khi map với giao thức/phần cứng
assert(condition)<cassert> — kiểm tra điều kiện lúc chạy (runtime), dừng chương trình nếu sai. Bị vô hiệu hóa khi build với NDEBUG (bản release) — không dùng để kiểm tra input từ người dùng/mạng (vì sẽ mất tác dụng ở production)
[[nodiscard]] (C++17)Đánh dấu hàm mà giá trị trả về không nên bị bỏ qua — compiler sẽ cảnh báo nếu người gọi quên kiểm tra (ví dụ hàm trả về mã lỗi)
[[maybe_unused]]Báo compiler không cảnh báo “biến/tham số không dùng đến” — hữu ích khi tham số chỉ cần cho một số cấu hình build
typeid(x).name()<typeinfo> — lấy tên kiểu lúc runtime (dùng với RTTI, hạn chế dùng trong embedded vì tăng kích thước binary)
__FILE__ / __LINE__ / __func__Macro có sẵn của compiler, hữu ích khi viết log/assert tùy chỉnh để biết chính xác vị trí lỗi
struct PacketHeader {
    uint16_t length;
    uint8_t  type;
    uint8_t  flags;
};
static_assert(sizeof(PacketHeader) == 4, "PacketHeader phải đúng 4 byte để khớp giao thức");

13. Bảng tra nhanh: “Đừng dùng cái này — dùng cái kia”

🔴 Tránh dùng🟢 Dùng thay thếLý do
strcpy, strcat, sprintf, getssnprintf, std::string, std::spanChống buffer overflow
new/delete trầnstd::make_unique/std::make_sharedTránh leak khi có exception
malloc không kiểm tramalloc + kiểm tra NULL luôn luônTránh crash âm thầm
Con trỏ thô để sở hữu tài nguyênSmart pointer (unique_ptr/shared_ptr)RAII, tự động giải phóng
memcmp cho dữ liệu bảo mậtCRYPTO_memcmp (constant-time)Chống timing attack
memset để xóa secretexplicit_bzero/memset_sCompiler không được tối ưu bỏ qua
rand() cho khóa/tokenRAND_bytes() (CSPRNG)Chống đoán được giá trị
(int)x (C-style cast)static_cast<int>(x)Rõ ràng, dễ tìm khi audit
#define CONST 100constexpr int kConst = 100;Có kiểm tra kiểu
printf(user_input)printf("%s", user_input)Chống format string vulnerability
Tự viết cryptoThư viện đã kiểm định (OpenSSL/mbedTLS)Chống lỗi cài đặt tinh vi
std::vector trong ISR/real-time pathstd::array hoặc buffer tĩnhĐảm bảo tính xác định (determinism)

Xem thêm file nguyen-tac-lap-trinh-C-CPP.md để hiểu bối cảnh và nguyên tắc đầy đủ khi áp dụng các method này trong dự án embedded/RTOS/viễn thông/an ninh mạng.

Contact
Facebook
TOP