[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M70GSQE4JDK5S6Y9849AH9SS":3,"skill-same:01M70GSQE4JDK5S6Y9849AH9SS":73},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":49,"commitSha":50,"skillDirectory":51,"forksCount":52,"repositoryHtmlUrl":53,"repositoryHomepageUrl":54,"ownerHtmlUrl":55,"ownerBlogUrl":56,"ownerDescription":57,"updatedAt":58,"install":59,"resources":72},"01M70GSQE4JDK5S6Y9849AH9SS","memory-safety-patterns",null,"Implement memory-safe programming with RAII, ownership, smart pointers, and resource management across Rust, C++, and C. Use when writing safe systems code, managing resources, or preventing memory bugs.","shengdabai\u002FTony-Claude-Code-Skills","shengdabai","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F116417419?v=4","01M70F6D2WY5PQV5A92BKYJQEW","Tony Sheng","01M70F6D3GAAAYZ5H4CC1G8VXM",3,"MIT","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002F_collections\u002Fplugins\u002Fsystems-programming\u002Fskills\u002Fmemory-safety-patterns\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"memory","memory safety","Safety","memory safety patterns","patterns","when","writing","bugs","resource management","with","raii","resources","across","c++","use","programming","code","implement","rust","safe","2026-11-10 10:12:30",false,"---\nname: memory-safety-patterns\ndescription: Implement memory-safe programming with RAII, ownership, smart pointers, and resource management across Rust, C++, and C. Use when writing safe systems code, managing resources, or preventing memory bugs.\n---\n\n# Memory Safety Patterns\n\nCross-language patterns for memory-safe programming including RAII, ownership, smart pointers, and resource management.\n\n## When to Use This Skill\n\n- Writing memory-safe systems code\n- Managing resources (files, sockets, memory)\n- Preventing use-after-free and leaks\n- Implementing RAII patterns\n- Choosing between languages for safety\n- Debugging memory issues\n\n## Core Concepts\n\n### 1. Memory Bug Categories\n\n| Bug Type | Description | Prevention |\n|----------|-------------|------------|\n| **Use-after-free** | Access freed memory | Ownership, RAII |\n| **Double-free** | Free same memory twice | Smart pointers |\n| **Memory leak** | Never free memory | RAII, GC |\n| **Buffer overflow** | Write past buffer end | Bounds checking |\n| **Dangling pointer** | Pointer to freed memory | Lifetime tracking |\n| **Data race** | Concurrent unsynchronized access | Ownership, Sync |\n\n### 2. Safety Spectrum\n\n```\nManual (C) → Smart Pointers (C++) → Ownership (Rust) → GC (Go, Java)\nLess safe                                              More safe\nMore control                                           Less control\n```\n\n## Patterns by Language\n\n### Pattern 1: RAII in C++\n\n```cpp\n\u002F\u002F RAII: Resource Acquisition Is Initialization\n\u002F\u002F Resource lifetime tied to object lifetime\n\n#include \u003Cmemory>\n#include \u003Cfstream>\n#include \u003Cmutex>\n\n\u002F\u002F File handle with RAII\nclass FileHandle {\npublic:\n    explicit FileHandle(const std::string& path)\n        : file_(path) {\n        if (!file_.is_open()) {\n            throw std::runtime_error(\"Failed to open file\");\n        }\n    }\n\n    \u002F\u002F Destructor automatically closes file\n    ~FileHandle() = default; \u002F\u002F fstream closes in its destructor\n\n    \u002F\u002F Delete copy (prevent double-close)\n    FileHandle(const FileHandle&) = delete;\n    FileHandle& operator=(const FileHandle&) = delete;\n\n    \u002F\u002F Allow move\n    FileHandle(FileHandle&&) = default;\n    FileHandle& operator=(FileHandle&&) = default;\n\n    void write(const std::string& data) {\n        file_ \u003C\u003C data;\n    }\n\nprivate:\n    std::fstream file_;\n};\n\n\u002F\u002F Lock guard (RAII for mutexes)\nclass Database {\npublic:\n    void update(const std::string& key, const std::string& value) {\n        std::lock_guard\u003Cstd::mutex> lock(mutex_); \u002F\u002F Released on scope exit\n        data_[key] = value;\n    }\n\n    std::string get(const std::string& key) {\n        std::shared_lock\u003Cstd::shared_mutex> lock(shared_mutex_);\n        return data_[key];\n    }\n\nprivate:\n    std::mutex mutex_;\n    std::shared_mutex shared_mutex_;\n    std::map\u003Cstd::string, std::string> data_;\n};\n\n\u002F\u002F Transaction with rollback (RAII)\ntemplate\u003Ctypename T>\nclass Transaction {\npublic:\n    explicit Transaction(T& target)\n        : target_(target), backup_(target), committed_(false) {}\n\n    ~Transaction() {\n        if (!committed_) {\n            target_ = backup_; \u002F\u002F Rollback\n        }\n    }\n\n    void commit() { committed_ = true; }\n\n    T& get() { return target_; }\n\nprivate:\n    T& target_;\n    T backup_;\n    bool committed_;\n};\n```\n\n### Pattern 2: Smart Pointers in C++\n\n```cpp\n#include \u003Cmemory>\n\n\u002F\u002F unique_ptr: Single ownership\nclass Engine {\npublic:\n    void start() { \u002F* ... *\u002F }\n};\n\nclass Car {\npublic:\n    Car() : engine_(std::make_unique\u003CEngine>()) {}\n\n    void start() {\n        engine_->start();\n    }\n\n    \u002F\u002F Transfer ownership\n    std::unique_ptr\u003CEngine> extractEngine() {\n        return std::move(engine_);\n    }\n\nprivate:\n    std::unique_ptr\u003CEngine> engine_;\n};\n\n\u002F\u002F shared_ptr: Shared ownership\nclass Node {\npublic:\n    std::string data;\n    std::shared_ptr\u003CNode> next;\n\n    \u002F\u002F Use weak_ptr to break cycles\n    std::weak_ptr\u003CNode> parent;\n};\n\nvoid sharedPtrExample() {\n    auto node1 = std::make_shared\u003CNode>();\n    auto node2 = std::make_shared\u003CNode>();\n\n    node1->next = node2;\n    node2->parent = node1; \u002F\u002F Weak reference prevents cycle\n\n    \u002F\u002F Access weak_ptr\n    if (auto parent = node2->parent.lock()) {\n        \u002F\u002F parent is valid shared_ptr\n    }\n}\n\n\u002F\u002F Custom deleter for resources\nclass Socket {\npublic:\n    static void close(int* fd) {\n        if (fd && *fd >= 0) {\n            ::close(*fd);\n            delete fd;\n        }\n    }\n};\n\nauto createSocket() {\n    int fd = socket(AF_INET, SOCK_STREAM, 0);\n    return std::unique_ptr\u003Cint, decltype(&Socket::close)>(\n        new int(fd),\n        &Socket::close\n    );\n}\n\n\u002F\u002F make_unique\u002Fmake_shared best practices\nvoid bestPractices() {\n    \u002F\u002F Good: Exception safe, single allocation\n    auto ptr = std::make_shared\u003CWidget>();\n\n    \u002F\u002F Bad: Two allocations, not exception safe\n    std::shared_ptr\u003CWidget> ptr2(new Widget());\n\n    \u002F\u002F For arrays\n    auto arr = std::make_unique\u003Cint[]>(10);\n}\n```\n\n### Pattern 3: Ownership in Rust\n\n```rust\n\u002F\u002F Move semantics (default)\nfn move_example() {\n    let s1 = String::from(\"hello\");\n    let s2 = s1; \u002F\u002F s1 is MOVED, no longer valid\n\n    \u002F\u002F println!(\"{}\", s1); \u002F\u002F Compile error!\n    println!(\"{}\", s2);\n}\n\n\u002F\u002F Borrowing (references)\nfn borrow_example() {\n    let s = String::from(\"hello\");\n\n    \u002F\u002F Immutable borrow (multiple allowed)\n    let len = calculate_length(&s);\n    println!(\"{} has length {}\", s, len);\n\n    \u002F\u002F Mutable borrow (only one allowed)\n    let mut s = String::from(\"hello\");\n    change(&mut s);\n}\n\nfn calculate_length(s: &String) -> usize {\n    s.len()\n} \u002F\u002F s goes out of scope, but doesn't drop since borrowed\n\nfn change(s: &mut String) {\n    s.push_str(\", world\");\n}\n\n\u002F\u002F Lifetimes: Compiler tracks reference validity\nfn longest\u003C'a>(x: &'a str, y: &'a str) -> &'a str {\n    if x.len() > y.len() { x } else { y }\n}\n\n\u002F\u002F Struct with references needs lifetime annotation\nstruct ImportantExcerpt\u003C'a> {\n    part: &'a str,\n}\n\nimpl\u003C'a> ImportantExcerpt\u003C'a> {\n    fn level(&self) -> i32 {\n        3\n    }\n\n    \u002F\u002F Lifetime elision: compiler infers 'a for &self\n    fn announce_and_return_part(&self, announcement: &str) -> &str {\n        println!(\"Attention: {}\", announcement);\n        self.part\n    }\n}\n\n\u002F\u002F Interior mutability\nuse std::cell::{Cell, RefCell};\nuse std::rc::Rc;\n\nstruct Stats {\n    count: Cell\u003Ci32>,           \u002F\u002F Copy types\n    data: RefCell\u003CVec\u003CString>>, \u002F\u002F Non-Copy types\n}\n\nimpl Stats {\n    fn increment(&self) {\n        self.count.set(self.count.get() + 1);\n    }\n\n    fn add_data(&self, item: String) {\n        self.data.borrow_mut().push(item);\n    }\n}\n\n\u002F\u002F Rc for shared ownership (single-threaded)\nfn rc_example() {\n    let data = Rc::new(vec![1, 2, 3]);\n    let data2 = Rc::clone(&data); \u002F\u002F Increment reference count\n\n    println!(\"Count: {}\", Rc::strong_count(&data)); \u002F\u002F 2\n}\n\n\u002F\u002F Arc for shared ownership (thread-safe)\nuse std::sync::Arc;\nuse std::thread;\n\nfn arc_example() {\n    let data = Arc::new(vec![1, 2, 3]);\n\n    let handles: Vec\u003C_> = (0..3)\n        .map(|_| {\n            let data = Arc::clone(&data);\n            thread::spawn(move || {\n                println!(\"{:?}\", data);\n            })\n        })\n        .collect();\n\n    for handle in handles {\n        handle.join().unwrap();\n    }\n}\n```\n\n### Pattern 4: Safe Resource Management in C\n\n```c\n\u002F\u002F C doesn't have RAII, but we can use patterns\n\n#include \u003Cstdlib.h>\n#include \u003Cstdio.h>\n\n\u002F\u002F Pattern: goto cleanup\nint process_file(const char* path) {\n    FILE* file = NULL;\n    char* buffer = NULL;\n    int result = -1;\n\n    file = fopen(path, \"r\");\n    if (!file) {\n        goto cleanup;\n    }\n\n    buffer = malloc(1024);\n    if (!buffer) {\n        goto cleanup;\n    }\n\n    \u002F\u002F Process file...\n    result = 0;\n\ncleanup:\n    if (buffer) free(buffer);\n    if (file) fclose(file);\n    return result;\n}\n\n\u002F\u002F Pattern: Opaque pointer with create\u002Fdestroy\ntypedef struct Context Context;\n\nContext* context_create(void);\nvoid context_destroy(Context* ctx);\nint context_process(Context* ctx, const char* data);\n\n\u002F\u002F Implementation\nstruct Context {\n    int* data;\n    size_t size;\n    FILE* log;\n};\n\nContext* context_create(void) {\n    Context* ctx = calloc(1, sizeof(Context));\n    if (!ctx) return NULL;\n\n    ctx->data = malloc(100 * sizeof(int));\n    if (!ctx->data) {\n        free(ctx);\n        return NULL;\n    }\n\n    ctx->log = fopen(\"log.txt\", \"w\");\n    if (!ctx->log) {\n        free(ctx->data);\n        free(ctx);\n        return NULL;\n    }\n\n    return ctx;\n}\n\nvoid context_destroy(Context* ctx) {\n    if (ctx) {\n        if (ctx->log) fclose(ctx->log);\n        if (ctx->data) free(ctx->data);\n        free(ctx);\n    }\n}\n\n\u002F\u002F Pattern: Cleanup attribute (GCC\u002FClang extension)\n#define AUTO_FREE __attribute__((cleanup(auto_free_func)))\n\nvoid auto_free_func(void** ptr) {\n    free(*ptr);\n}\n\nvoid auto_free_example(void) {\n    AUTO_FREE char* buffer = malloc(1024);\n    \u002F\u002F buffer automatically freed at end of scope\n}\n```\n\n### Pattern 5: Bounds Checking\n\n```cpp\n\u002F\u002F C++: Use containers instead of raw arrays\n#include \u003Cvector>\n#include \u003Carray>\n#include \u003Cspan>\n\nvoid safe_array_access() {\n    std::vector\u003Cint> vec = {1, 2, 3, 4, 5};\n\n    \u002F\u002F Safe: throws std::out_of_range\n    try {\n        int val = vec.at(10);\n    } catch (const std::out_of_range& e) {\n        \u002F\u002F Handle error\n    }\n\n    \u002F\u002F Unsafe but faster (no bounds check)\n    int val = vec[2];\n\n    \u002F\u002F Modern C++20: std::span for array views\n    std::span\u003Cint> view(vec);\n    \u002F\u002F Iterators are bounds-safe\n    for (int& x : view) {\n        x *= 2;\n    }\n}\n\n\u002F\u002F Fixed-size arrays\nvoid fixed_array() {\n    std::array\u003Cint, 5> arr = {1, 2, 3, 4, 5};\n\n    \u002F\u002F Compile-time size known\n    static_assert(arr.size() == 5);\n\n    \u002F\u002F Safe access\n    int val = arr.at(2);\n}\n```\n\n```rust\n\u002F\u002F Rust: Bounds checking by default\n\nfn rust_bounds_checking() {\n    let vec = vec![1, 2, 3, 4, 5];\n\n    \u002F\u002F Runtime bounds check (panics if out of bounds)\n    let val = vec[2];\n\n    \u002F\u002F Explicit option (no panic)\n    match vec.get(10) {\n        Some(val) => println!(\"Got {}\", val),\n        None => println!(\"Index out of bounds\"),\n    }\n\n    \u002F\u002F Iterators (no bounds checking needed)\n    for val in &vec {\n        println!(\"{}\", val);\n    }\n\n    \u002F\u002F Slices are bounds-checked\n    let slice = &vec[1..3]; \u002F\u002F [2, 3]\n}\n```\n\n### Pattern 6: Preventing Data Races\n\n```cpp\n\u002F\u002F C++: Thread-safe shared state\n#include \u003Cmutex>\n#include \u003Cshared_mutex>\n#include \u003Catomic>\n\nclass ThreadSafeCounter {\npublic:\n    void increment() {\n        \u002F\u002F Atomic operations\n        count_.fetch_add(1, std::memory_order_relaxed);\n    }\n\n    int get() const {\n        return count_.load(std::memory_order_relaxed);\n    }\n\nprivate:\n    std::atomic\u003Cint> count_{0};\n};\n\nclass ThreadSafeMap {\npublic:\n    void write(const std::string& key, int value) {\n        std::unique_lock lock(mutex_);\n        data_[key] = value;\n    }\n\n    std::optional\u003Cint> read(const std::string& key) {\n        std::shared_lock lock(mutex_);\n        auto it = data_.find(key);\n        if (it != data_.end()) {\n            return it->second;\n        }\n        return std::nullopt;\n    }\n\nprivate:\n    mutable std::shared_mutex mutex_;\n    std::map\u003Cstd::string, int> data_;\n};\n```\n\n```rust\n\u002F\u002F Rust: Data race prevention at compile time\n\nuse std::sync::{Arc, Mutex, RwLock};\nuse std::sync::atomic::{AtomicI32, Ordering};\nuse std::thread;\n\n\u002F\u002F Atomic for simple types\nfn atomic_example() {\n    let counter = Arc::new(AtomicI32::new(0));\n\n    let handles: Vec\u003C_> = (0..10)\n        .map(|_| {\n            let counter = Arc::clone(&counter);\n            thread::spawn(move || {\n                counter.fetch_add(1, Ordering::SeqCst);\n            })\n        })\n        .collect();\n\n    for handle in handles {\n        handle.join().unwrap();\n    }\n\n    println!(\"Counter: {}\", counter.load(Ordering::SeqCst));\n}\n\n\u002F\u002F Mutex for complex types\nfn mutex_example() {\n    let data = Arc::new(Mutex::new(vec![]));\n\n    let handles: Vec\u003C_> = (0..10)\n        .map(|i| {\n            let data = Arc::clone(&data);\n            thread::spawn(move || {\n                let mut vec = data.lock().unwrap();\n                vec.push(i);\n            })\n        })\n        .collect();\n\n    for handle in handles {\n        handle.join().unwrap();\n    }\n}\n\n\u002F\u002F RwLock for read-heavy workloads\nfn rwlock_example() {\n    let data = Arc::new(RwLock::new(HashMap::new()));\n\n    \u002F\u002F Multiple readers OK\n    let read_guard = data.read().unwrap();\n\n    \u002F\u002F Writer blocks readers\n    let write_guard = data.write().unwrap();\n}\n```\n\n## Best Practices\n\n### Do's\n- **Prefer RAII** - Tie resource lifetime to scope\n- **Use smart pointers** - Avoid raw pointers in C++\n- **Understand ownership** - Know who owns what\n- **Check bounds** - Use safe access methods\n- **Use tools** - AddressSanitizer, Valgrind, Miri\n\n### Don'ts\n- **Don't use raw pointers** - Unless interfacing with C\n- **Don't return local references** - Dangling pointer\n- **Don't ignore compiler warnings** - They catch bugs\n- **Don't use `unsafe` carelessly** - In Rust, minimize it\n- **Don't assume thread safety** - Be explicit\n\n## Debugging Tools\n\n```bash\n# AddressSanitizer (Clang\u002FGCC)\nclang++ -fsanitize=address -g source.cpp\n\n# Valgrind\nvalgrind --leak-check=full .\u002Fprogram\n\n# Rust Miri (undefined behavior detector)\ncargo +nightly miri run\n\n# ThreadSanitizer\nclang++ -fsanitize=thread -g source.cpp\n```\n\n## Resources\n\n- [C++ Core Guidelines](https:\u002F\u002Fisocpp.github.io\u002FCppCoreGuidelines\u002F)\n- [Rust Ownership](https:\u002F\u002Fdoc.rust-lang.org\u002Fbook\u002Fch04-00-understanding-ownership.html)\n- [AddressSanitizer](https:\u002F\u002Fclang.llvm.org\u002Fdocs\u002FAddressSanitizer.html)\n","# Memory Safety Patterns\n\nCross-language patterns for memory-safe programming including RAII, ownership, smart pointers, and resource management.\n\n## When to Use This Skill\n\n- Writing memory-safe systems code\n- Managing resources (files, sockets, memory)\n- Preventing use-after-free and leaks\n- Implementing RAII patterns\n- Choosing between languages for safety\n- Debugging memory issues\n\n## Core Concepts\n\n### 1. Memory Bug Categories\n\n| Bug Type | Description | Prevention |\n|----------|-------------|------------|\n| **Use-after-free** | Access freed memory | Ownership, RAII |\n| **Double-free** | Free same memory twice | Smart pointers |\n| **Memory leak** | Never free memory | RAII, GC |\n| **Buffer overflow** | Write past buffer end | Bounds checking |\n| **Dangling pointer** | Pointer to freed memory | Lifetime tracking |\n| **Data race** | Concurrent unsynchronized access | Ownership, Sync |\n\n### 2. Safety Spectrum\n\n```\nManual (C) → Smart Pointers (C++) → Ownership (Rust) → GC (Go, Java)\nLess safe                                              More safe\nMore control                                           Less control\n```\n\n## Patterns by Language\n\n### Pattern 1: RAII in C++\n\n```cpp\n\u002F\u002F RAII: Resource Acquisition Is Initialization\n\u002F\u002F Resource lifetime tied to object lifetime\n\n#include \u003Cmemory>\n#include \u003Cfstream>\n#include \u003Cmutex>\n\n\u002F\u002F File handle with RAII\nclass FileHandle {\npublic:\n    explicit FileHandle(const std::string& path)\n        : file_(path) {\n        if (!file_.is_open()) {\n            throw std::runtime_error(\"Failed to open file\");\n        }\n    }\n\n    \u002F\u002F Destructor automatically closes file\n    ~FileHandle() = default; \u002F\u002F fstream closes in its destructor\n\n    \u002F\u002F Delete copy (prevent double-close)\n    FileHandle(const FileHandle&) = delete;\n    FileHandle& operator=(const FileHandle&) = delete;\n\n    \u002F\u002F Allow move\n    FileHandle(FileHandle&&) = default;\n    FileHandle& operator=(FileHandle&&) = default;\n\n    void write(const std::string& data) {\n        file_ \u003C\u003C data;\n    }\n\nprivate:\n    std::fstream file_;\n};\n\n\u002F\u002F Lock guard (RAII for mutexes)\nclass Database {\npublic:\n    void update(const std::string& key, const std::string& value) {\n        std::lock_guard\u003Cstd::mutex> lock(mutex_); \u002F\u002F Released on scope exit\n        data_[key] = value;\n    }\n\n    std::string get(const std::string& key) {\n        std::shared_lock\u003Cstd::shared_mutex> lock(shared_mutex_);\n        return data_[key];\n    }\n\nprivate:\n    std::mutex mutex_;\n    std::shared_mutex shared_mutex_;\n    std::map\u003Cstd::string, std::string> data_;\n};\n\n\u002F\u002F Transaction with rollback (RAII)\ntemplate\u003Ctypename T>\nclass Transaction {\npublic:\n    explicit Transaction(T& target)\n        : target_(target), backup_(target), committed_(false) {}\n\n    ~Transaction() {\n        if (!committed_) {\n            target_ = backup_; \u002F\u002F Rollback\n        }\n    }\n\n    void commit() { committed_ = true; }\n\n    T& get() { return target_; }\n\nprivate:\n    T& target_;\n    T backup_;\n    bool committed_;\n};\n```\n\n### Pattern 2: Smart Pointers in C++\n\n```cpp\n#include \u003Cmemory>\n\n\u002F\u002F unique_ptr: Single ownership\nclass Engine {\npublic:\n    void start() { \u002F* ... *\u002F }\n};\n\nclass Car {\npublic:\n    Car() : engine_(std::make_unique\u003CEngine>()) {}\n\n    void start() {\n        engine_->start();\n    }\n\n    \u002F\u002F Transfer ownership\n    std::unique_ptr\u003CEngine> extractEngine() {\n        return std::move(engine_);\n    }\n\nprivate:\n    std::unique_ptr\u003CEngine> engine_;\n};\n\n\u002F\u002F shared_ptr: Shared ownership\nclass Node {\npublic:\n    std::string data;\n    std::shared_ptr\u003CNode> next;\n\n    \u002F\u002F Use weak_ptr to break cycles\n    std::weak_ptr\u003CNode> parent;\n};\n\nvoid sharedPtrExample() {\n    auto node1 = std::make_shared\u003CNode>();\n    auto node2 = std::make_shared\u003CNode>();\n\n    node1->next = node2;\n    node2->parent = node1; \u002F\u002F Weak reference prevents cycle\n\n    \u002F\u002F Access weak_ptr\n    if (auto parent = node2->parent.lock()) {\n        \u002F\u002F parent is valid shared_ptr\n    }\n}\n\n\u002F\u002F Custom deleter for resources\nclass Socket {\npublic:\n    static void close(int* fd) {\n        if (fd && *fd >= 0) {\n            ::close(*fd);\n            delete fd;\n        }\n    }\n};\n\nauto createSocket() {\n    int fd = socket(AF_INET, SOCK_STREAM, 0);\n    return std::unique_ptr\u003Cint, decltype(&Socket::close)>(\n        new int(fd),\n        &Socket::close\n    );\n}\n\n\u002F\u002F make_unique\u002Fmake_shared best practices\nvoid bestPractices() {\n    \u002F\u002F Good: Exception safe, single allocation\n    auto ptr = std::make_shared\u003CWidget>();\n\n    \u002F\u002F Bad: Two allocations, not exception safe\n    std::shared_ptr\u003CWidget> ptr2(new Widget());\n\n    \u002F\u002F For arrays\n    auto arr = std::make_unique\u003Cint[]>(10);\n}\n```\n\n### Pattern 3: Ownership in Rust\n\n```rust\n\u002F\u002F Move semantics (default)\nfn move_example() {\n    let s1 = String::from(\"hello\");\n    let s2 = s1; \u002F\u002F s1 is MOVED, no longer valid\n\n    \u002F\u002F println!(\"{}\", s1); \u002F\u002F Compile error!\n    println!(\"{}\", s2);\n}\n\n\u002F\u002F Borrowing (references)\nfn borrow_example() {\n    let s = String::from(\"hello\");\n\n    \u002F\u002F Immutable borrow (multiple allowed)\n    let len = calculate_length(&s);\n    println!(\"{} has length {}\", s, len);\n\n    \u002F\u002F Mutable borrow (only one allowed)\n    let mut s = String::from(\"hello\");\n    change(&mut s);\n}\n\nfn calculate_length(s: &String) -> usize {\n    s.len()\n} \u002F\u002F s goes out of scope, but doesn't drop since borrowed\n\nfn change(s: &mut String) {\n    s.push_str(\", world\");\n}\n\n\u002F\u002F Lifetimes: Compiler tracks reference validity\nfn longest\u003C'a>(x: &'a str, y: &'a str) -> &'a str {\n    if x.len() > y.len() { x } else { y }\n}\n\n\u002F\u002F Struct with references needs lifetime annotation\nstruct ImportantExcerpt\u003C'a> {\n    part: &'a str,\n}\n\nimpl\u003C'a> ImportantExcerpt\u003C'a> {\n    fn level(&self) -> i32 {\n        3\n    }\n\n    \u002F\u002F Lifetime elision: compiler infers 'a for &self\n    fn announce_and_return_part(&self, announcement: &str) -> &str {\n        println!(\"Attention: {}\", announcement);\n        self.part\n    }\n}\n\n\u002F\u002F Interior mutability\nuse std::cell::{Cell, RefCell};\nuse std::rc::Rc;\n\nstruct Stats {\n    count: Cell\u003Ci32>,           \u002F\u002F Copy types\n    data: RefCell\u003CVec\u003CString>>, \u002F\u002F Non-Copy types\n}\n\nimpl Stats {\n    fn increment(&self) {\n        self.count.set(self.count.get() + 1);\n    }\n\n    fn add_data(&self, item: String) {\n        self.data.borrow_mut().push(item);\n    }\n}\n\n\u002F\u002F Rc for shared ownership (single-threaded)\nfn rc_example() {\n    let data = Rc::new(vec![1, 2, 3]);\n    let data2 = Rc::clone(&data); \u002F\u002F Increment reference count\n\n    println!(\"Count: {}\", Rc::strong_count(&data)); \u002F\u002F 2\n}\n\n\u002F\u002F Arc for shared ownership (thread-safe)\nuse std::sync::Arc;\nuse std::thread;\n\nfn arc_example() {\n    let data = Arc::new(vec![1, 2, 3]);\n\n    let handles: Vec\u003C_> = (0..3)\n        .map(|_| {\n            let data = Arc::clone(&data);\n            thread::spawn(move || {\n                println!(\"{:?}\", data);\n            })\n        })\n        .collect();\n\n    for handle in handles {\n        handle.join().unwrap();\n    }\n}\n```\n\n### Pattern 4: Safe Resource Management in C\n\n```c\n\u002F\u002F C doesn't have RAII, but we can use patterns\n\n#include \u003Cstdlib.h>\n#include \u003Cstdio.h>\n\n\u002F\u002F Pattern: goto cleanup\nint process_file(const char* path) {\n    FILE* file = NULL;\n    char* buffer = NULL;\n    int result = -1;\n\n    file = fopen(path, \"r\");\n    if (!file) {\n        goto cleanup;\n    }\n\n    buffer = malloc(1024);\n    if (!buffer) {\n        goto cleanup;\n    }\n\n    \u002F\u002F Process file...\n    result = 0;\n\ncleanup:\n    if (buffer) free(buffer);\n    if (file) fclose(file);\n    return result;\n}\n\n\u002F\u002F Pattern: Opaque pointer with create\u002Fdestroy\ntypedef struct Context Context;\n\nContext* context_create(void);\nvoid context_destroy(Context* ctx);\nint context_process(Context* ctx, const char* data);\n\n\u002F\u002F Implementation\nstruct Context {\n    int* data;\n    size_t size;\n    FILE* log;\n};\n\nContext* context_create(void) {\n    Context* ctx = calloc(1, sizeof(Context));\n    if (!ctx) return NULL;\n\n    ctx->data = malloc(100 * sizeof(int));\n    if (!ctx->data) {\n        free(ctx);\n        return NULL;\n    }\n\n    ctx->log = fopen(\"log.txt\", \"w\");\n    if (!ctx->log) {\n        free(ctx->data);\n        free(ctx);\n        return NULL;\n    }\n\n    return ctx;\n}\n\nvoid context_destroy(Context* ctx) {\n    if (ctx) {\n        if (ctx->log) fclose(ctx->log);\n        if (ctx->data) free(ctx->data);\n        free(ctx);\n    }\n}\n\n\u002F\u002F Pattern: Cleanup attribute (GCC\u002FClang extension)\n#define AUTO_FREE __attribute__((cleanup(auto_free_func)))\n\nvoid auto_free_func(void** ptr) {\n    free(*ptr);\n}\n\nvoid auto_free_example(void) {\n    AUTO_FREE char* buffer = malloc(1024);\n    \u002F\u002F buffer automatically freed at end of scope\n}\n```\n\n### Pattern 5: Bounds Checking\n\n```cpp\n\u002F\u002F C++: Use containers instead of raw arrays\n#include \u003Cvector>\n#include \u003Carray>\n#include \u003Cspan>\n\nvoid safe_array_access() {\n    std::vector\u003Cint> vec = {1, 2, 3, 4, 5};\n\n    \u002F\u002F Safe: throws std::out_of_range\n    try {\n        int val = vec.at(10);\n    } catch (const std::out_of_range& e) {\n        \u002F\u002F Handle error\n    }\n\n    \u002F\u002F Unsafe but faster (no bounds check)\n    int val = vec[2];\n\n    \u002F\u002F Modern C++20: std::span for array views\n    std::span\u003Cint> view(vec);\n    \u002F\u002F Iterators are bounds-safe\n    for (int& x : view) {\n        x *= 2;\n    }\n}\n\n\u002F\u002F Fixed-size arrays\nvoid fixed_array() {\n    std::array\u003Cint, 5> arr = {1, 2, 3, 4, 5};\n\n    \u002F\u002F Compile-time size known\n    static_assert(arr.size() == 5);\n\n    \u002F\u002F Safe access\n    int val = arr.at(2);\n}\n```\n\n```rust\n\u002F\u002F Rust: Bounds checking by default\n\nfn rust_bounds_checking() {\n    let vec = vec![1, 2, 3, 4, 5];\n\n    \u002F\u002F Runtime bounds check (panics if out of bounds)\n    let val = vec[2];\n\n    \u002F\u002F Explicit option (no panic)\n    match vec.get(10) {\n        Some(val) => println!(\"Got {}\", val),\n        None => println!(\"Index out of bounds\"),\n    }\n\n    \u002F\u002F Iterators (no bounds checking needed)\n    for val in &vec {\n        println!(\"{}\", val);\n    }\n\n    \u002F\u002F Slices are bounds-checked\n    let slice = &vec[1..3]; \u002F\u002F [2, 3]\n}\n```\n\n### Pattern 6: Preventing Data Races\n\n```cpp\n\u002F\u002F C++: Thread-safe shared state\n#include \u003Cmutex>\n#include \u003Cshared_mutex>\n#include \u003Catomic>\n\nclass ThreadSafeCounter {\npublic:\n    void increment() {\n        \u002F\u002F Atomic operations\n        count_.fetch_add(1, std::memory_order_relaxed);\n    }\n\n    int get() const {\n        return count_.load(std::memory_order_relaxed);\n    }\n\nprivate:\n    std::atomic\u003Cint> count_{0};\n};\n\nclass ThreadSafeMap {\npublic:\n    void write(const std::string& key, int value) {\n        std::unique_lock lock(mutex_);\n        data_[key] = value;\n    }\n\n    std::optional\u003Cint> read(const std::string& key) {\n        std::shared_lock lock(mutex_);\n        auto it = data_.find(key);\n        if (it != data_.end()) {\n            return it->second;\n        }\n        return std::nullopt;\n    }\n\nprivate:\n    mutable std::shared_mutex mutex_;\n    std::map\u003Cstd::string, int> data_;\n};\n```\n\n```rust\n\u002F\u002F Rust: Data race prevention at compile time\n\nuse std::sync::{Arc, Mutex, RwLock};\nuse std::sync::atomic::{AtomicI32, Ordering};\nuse std::thread;\n\n\u002F\u002F Atomic for simple types\nfn atomic_example() {\n    let counter = Arc::new(AtomicI32::new(0));\n\n    let handles: Vec\u003C_> = (0..10)\n        .map(|_| {\n            let counter = Arc::clone(&counter);\n            thread::spawn(move || {\n                counter.fetch_add(1, Ordering::SeqCst);\n            })\n        })\n        .collect();\n\n    for handle in handles {\n        handle.join().unwrap();\n    }\n\n    println!(\"Counter: {}\", counter.load(Ordering::SeqCst));\n}\n\n\u002F\u002F Mutex for complex types\nfn mutex_example() {\n    let data = Arc::new(Mutex::new(vec![]));\n\n    let handles: Vec\u003C_> = (0..10)\n        .map(|i| {\n            let data = Arc::clone(&data);\n            thread::spawn(move || {\n                let mut vec = data.lock().unwrap();\n                vec.push(i);\n            })\n        })\n        .collect();\n\n    for handle in handles {\n        handle.join().unwrap();\n    }\n}\n\n\u002F\u002F RwLock for read-heavy workloads\nfn rwlock_example() {\n    let data = Arc::new(RwLock::new(HashMap::new()));\n\n    \u002F\u002F Multiple readers OK\n    let read_guard = data.read().unwrap();\n\n    \u002F\u002F Writer blocks readers\n    let write_guard = data.write().unwrap();\n}\n```\n\n## Best Practices\n\n### Do's\n- **Prefer RAII** - Tie resource lifetime to scope\n- **Use smart pointers** - Avoid raw pointers in C++\n- **Understand ownership** - Know who owns what\n- **Check bounds** - Use safe access methods\n- **Use tools** - AddressSanitizer, Valgrind, Miri\n\n### Don'ts\n- **Don't use raw pointers** - Unless interfacing with C\n- **Don't return local references** - Dangling pointer\n- **Don't ignore compiler warnings** - They catch bugs\n- **Don't use `unsafe` carelessly** - In Rust, minimize it\n- **Don't assume thread safety** - Be explicit\n\n## Debugging Tools\n\n```bash\n# AddressSanitizer (Clang\u002FGCC)\nclang++ -fsanitize=address -g source.cpp\n\n# Valgrind\nvalgrind --leak-check=full .\u002Fprogram\n\n# Rust Miri (undefined behavior detector)\ncargo +nightly miri run\n\n# ThreadSanitizer\nclang++ -fsanitize=thread -g source.cpp\n```\n\n## Resources\n\n- [C++ Core Guidelines](https:\u002F\u002Fisocpp.github.io\u002FCppCoreGuidelines\u002F)\n- [Rust Ownership](https:\u002F\u002Fdoc.rust-lang.org\u002Fbook\u002Fch04-00-understanding-ownership.html)\n- [AddressSanitizer](https:\u002F\u002Fclang.llvm.org\u002Fdocs\u002FAddressSanitizer.html)\n",{"name":5,"description":7},"main","7850740bd837adb32f0a109ab2af82482196c6f2","skills\u002F_collections\u002Fplugins\u002Fsystems-programming\u002Fskills\u002Fmemory-safety-patterns",1,"https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills","https:\u002F\u002Fzturnsgo.com","https:\u002F\u002Fgithub.com\u002Fshengdabai","https:\u002F\u002Fzturnsgo.com\u002F","AI × education creator — producer, not consumer. Taught 6,000+ learners; shipping learning tools & daily essays with Claude Code, practicing @xiaolai's way 🥋","2026-11-01 21:28:23",{"source":8,"skillName":5,"commands":60,"prompt":70,"zipAvailable":71},[61,64,67],{"tool":62,"command":63},"npx","npx skills add shengdabai\u002FTony-Claude-Code-Skills --skill memory-safety-patterns",{"tool":65,"command":66},"bunx","bunx skills add shengdabai\u002FTony-Claude-Code-Skills --skill memory-safety-patterns",{"tool":68,"command":69},"pnpm","pnpm dlx skills add shengdabai\u002FTony-Claude-Code-Skills --skill memory-safety-patterns","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002F_collections\u002Fplugins\u002Fsystems-programming\u002Fskills\u002Fmemory-safety-patterns\u002FSKILL.md",true,[],[74,92,121,146,168,188],{"skillNo":75,"name":76,"nameZh":6,"description":77,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":78,"categories":79,"keywords":85,"publishedAt":44},"01M70P17DAD4C1C47NPH6A96EM","xiaolai-methodology","以李笑来(Li Xiaolai)的思考方式、方法论与表达风格,为用户做全方位 1-on-1 教练指导,覆盖创业、赚钱、投资、学习、自学、读书写作、用 AI、以及人生心态与自我管理。当用户提到 \"李笑来\"、\"笑来\"、\"笑来老师\"、\"扮演李笑来\"、\"找笑来聊聊\"、\"笑来怎么看\"、\"xiaolai\"、\"把时间当作朋友\"、\"通往财富自由之路\"、\"定投改变命运\"、\"韭菜的自我修养\"、\"自学是门手艺\"、\"让时间陪你慢慢变富\"、\"七年就是一辈子\"、\"元认知\"、\"活在未来\"、\"复利\u002F长期主义\"、\"践行\"、\"痴迷改进\"、\"个人商业模式\u002F出售时间\"、\"睡后收入\"、\"定投\"、\"财富自由\"、\"操作系统升级\"、\"最少必要知识\"、\"北极星提示词\"、\"用 AI 该怎么学\u002F思考\" 等任一触发词,或当用户带着关于创业\u002F赚钱\u002F投资\u002F学习\u002F职业\u002F重大人生决策的困惑、希望被人用笑来式的「逻辑 + 大白话 + 类比 + 重新定义 + 践行导向」来点醒和指导时,自动进入李笑来教练模式。","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fxiaolai-methodology\u002FSKILL.md",[80],{"categoryNo":81,"categoryName":82,"taxonomyType":83,"taxonomyTypeDesc":84},"01JBSEEDCAT000000000000018","写作与文案","SCENARIO","使用场景",[86,87,88,89,90,30,91],"methodology","xiaolai","xiaolai methodology","朋友","投资","收入",{"skillNo":93,"name":94,"nameZh":6,"description":95,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":102,"publishedAt":44},"01M70P13NB9YP7ACJR1S861CDS","zread","Produce and consume a wiki-style knowledge base for a code repository via the `zread` CLI and its on-disk output under `.\u002F.zread\u002Fwiki\u002F`. Use this skill whenever the user wants to understand, onboard onto, explore, summarize, map, or get an overview of an unfamiliar codebase; asks for architecture docs, a project wiki, a repo walkthrough, module\u002Fpackage explanations, or \"what does this repo do\"; wants to generate, regenerate, resume, browse, or serve code documentation locally; or mentions zread \u002F zread.ai directly. Also use it proactively before diving into a large unknown repo — if `.\u002F.zread\u002Fwiki\u002Fcurrent` exists, read the generated pages instead of crawling source file-by-file; if it doesn't, consider offering to run `zread generate`. The trigger is the intent (understand a codebase through generated docs), not the literal word \"zread\".","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fzread\u002FSKILL.md",[98,101],{"categoryNo":99,"categoryName":100,"taxonomyType":83,"taxonomyTypeDesc":84},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[94,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,40,119,120],"knowledge","wiki","explore","walkthrough","project","get","knowledge base","run","generate","intent","cli","map","documentation","project wiki","disk","architecture","unknown","generated",{"skillNo":122,"name":123,"nameZh":6,"description":124,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":125,"categories":126,"keywords":131,"publishedAt":44},"01M70P10S4SWMZQ8BJAFBFDRW3","youtube","Launch the YouTube Creator Agent to auto-generate videos.\nUse when: user types \u002Fyoutube, wants to create YouTube videos,\ngenerate video content, or upload to YouTube.\nKeywords: youtube, video, 视频, 创作视频, 发布视频","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fyoutube\u002FSKILL.md",[127,128],{"categoryNo":99,"categoryName":100,"taxonomyType":83,"taxonomyTypeDesc":84},{"categoryNo":129,"categoryName":130,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000036","内容创作者",[123,132,133,134,135,136,137,138,111,139,140,141,29,38,142,143,144,145],"user","content","视频","creator","generate video","videos","launch","video content","create","upload","auto","types","Video","创作",{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":150,"categories":151,"keywords":153,"publishedAt":44},"01M70P0YE95D8BACZCGV8BK90K","youtube-script-sync","Sync, update, or optimize Tony's GetNote knowledge base `Youtube视频逐字稿` by turning each parent recording or first-person idea note into an idempotent child note containing a directly recordable YouTube long-video or Shorts script. Use when the user says “更新\u002F同步\u002F优化 Youtube视频逐字稿知识库”, or says “更新\u002F同步\u002F优化该知识库” while this knowledge base is the active context.","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fyoutube-script-sync\u002FSKILL.md",[152],{"categoryNo":99,"categoryName":100,"taxonomyType":83,"taxonomyTypeDesc":84},[154,155,123,156,157,144,158,159,160,161,162,163,164,165,109,166,29,38,103,167],"sync","script","youtube script sync","recording","shorts","first","base","person","update","active","child","optimize","idempotent","long",{"skillNo":169,"name":170,"nameZh":6,"description":171,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":172,"categories":173,"keywords":178,"publishedAt":44},"01M70P0WMV5XT0EEC0N445PW07","writing-skills","How to write SKILL.md files that trigger reliably and teach effectively. Use when creating, improving, or reviewing Claude Code skills.","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fxiaolai\u002Fnlpm\u002Fskills\u002Fnlpm\u002Fwriting-skills\u002FSKILL.md",[174,175,176,177],{"categoryNo":81,"categoryName":82,"taxonomyType":83,"taxonomyTypeDesc":84},{"categoryNo":99,"categoryName":100,"taxonomyType":83,"taxonomyTypeDesc":84},{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":129,"categoryName":130,"taxonomyType":21,"taxonomyTypeDesc":22},[179,30,180,181,182,183,40,29,38,184,185,186,187],"writing skills","how","teach","write skill","write","claude code skills","files","how to","trigger",{"skillNo":189,"name":190,"nameZh":6,"description":191,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":192,"categories":193,"keywords":196,"publishedAt":44},"01M70P0SJFR4YVJQBGMHKGSKXT","writing-rules","How to write .claude\u002Frules\u002F files that Claude actually follows. Use when creating, improving, or reviewing project rules.","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fxiaolai\u002Fnlpm\u002Fskills\u002Fnlpm\u002Fwriting-rules\u002FSKILL.md",[194,195],{"categoryNo":81,"categoryName":82,"taxonomyType":83,"taxonomyTypeDesc":84},{"categoryNo":129,"categoryName":130,"taxonomyType":21,"taxonomyTypeDesc":22},[197,30,198,107,199,185,29,180,183,38,186],"Rules","writing rules","project rules"]