1-2-2 Kotlin与C++基础-C++基础语法与内存管理

🏗️ C++基础语法与内存管理深度指南

一、C++基础语法核心要点

1.1 C++基础语法速览

1.1.1 基本程序结构
cpp 复制代码
// 标准C++程序模板
#include <iostream>     // 输入输出流
#include <string>       // 字符串类
using namespace std;    // 使用std命名空间(慎用)

int main() {            // 主函数
    // 基本输出
    cout << "Hello, C++!" << endl;
    
    // 变量声明与初始化
    int age = 25;                       // 传统初始化
    double price {99.99};               // C++11统一初始化
    auto name = "Alice"s;               // C++14自动类型推导
    
    // 常量
    const int MAX_SIZE = 100;
    constexpr double PI = 3.14159;      // 编译时常量
    
    // 引用(别名)
    int& refAge = age;                  // refAge是age的别名
    refAge = 30;                        // 同时修改了age
    
    // 指针
    int* ptr = &age;                    // ptr指向age的地址
    *ptr = 35;                          // 通过指针修改值
    
    return 0;                           // 程序正常退出
}
1.1.2 现代C++类型系统
cpp 复制代码
#include <iostream>
#include <typeinfo>
#include <vector>

int main() {
    // 1. 基本类型
    bool flag = true;                   // 布尔型(1字节)
    char ch = 'A';                      // 字符型(1字节)
    wchar_t wch = L'字';               // 宽字符
    char16_t c16 = u'字';              // UTF-16字符(C++11)
    char32_t c32 = U'字';              // UTF-32字符(C++11)
    
    // 2. 整型(带符号)
    short s = 100;                      // 短整型(通常2字节)
    int i = 1000;                       // 整型(通常4字节)
    long l = 10000L;                    // 长整型
    long long ll = 100000LL;            // 长长整型(C++11)
    
    // 3. 浮点型
    float f = 3.14f;                    // 单精度浮点(4字节)
    double d = 3.1415926535;            // 双精度浮点(8字节)
    long double ld = 3.141592653589793238L; // 扩展精度
    
    // 4. 类型推导(C++11起)
    auto x = 42;                        // x的类型是int
    auto y = 3.14;                      // y的类型是double
    auto z = "Hello";                   // z的类型是const char*
    
    // decltype获取表达式类型
    decltype(x) copyX = x;              // copyX的类型是int
    decltype((x)) refX = x;             // refX的类型是int&
    
    // 5. 类型别名(更易读)
    using String = std::string;         // C++11方式
    typedef std::vector<int> IntVec;    // 传统方式
    
    return 0;
}

1.2 函数进阶特性

cpp 复制代码
#include <iostream>
#include <functional>

// 1. 函数重载(Overloading)
void print(int value) {
    cout << "整数: " << value << endl;
}

void print(double value) {
    cout << "浮点数: " << value << endl;
}

void print(const std::string& value) {
    cout << "字符串: " << value << endl;
}

// 2. 默认参数
void setup(int width = 800, int height = 600, bool fullscreen = false) {
    cout << "分辨率: " << width << "x" << height 
         << ", 全屏: " << fullscreen << endl;
}

// 3. 内联函数(减少函数调用开销)
inline int square(int x) {
    return x * x;
}

// 4. 常量表达式函数(C++11)
constexpr int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

// 5. Lambda表达式(C++11)
auto lambdaExample() {
    // 基本lambda
    auto add = [](int a, int b) { return a + b; };
    
    // 捕获列表
    int multiplier = 3;
    auto times = [multiplier](int x) { return x * multiplier; };
    
    // 通用lambda(C++14)
    auto generic = [](auto a, auto b) { return a + b; };
    
    return add(5, 3); // 返回8
}

// 6. 函数指针和std::function
void demoFunctionTypes() {
    // 函数指针
    int (*funcPtr)(int, int) = nullptr;
    funcPtr = [](int a, int b) { return a * b; };
    
    // std::function(更安全灵活)
    std::function<int(int, int)> func;
    func = [](int a, int b) { return a + b; };
    
    // 绑定参数
    auto addFive = std::bind(func, std::placeholders::_1, 5);
    cout << addFive(10) << endl; // 输出15
}

int main() {
    print(42);              // 调用print(int)
    print(3.14);            // 调用print(double)
    print("Hello");         // 调用print(const string&)
    
    setup();                // 使用所有默认参数
    setup(1024);            // 只提供width
    setup(1920, 1080, true);// 提供所有参数
    
    cout << "5的平方: " << square(5) << endl;
    cout << "5的阶乘: " << factorial(5) << endl;
    
    return 0;
}

二、面向对象编程深入

2.1 类与对象

cpp 复制代码
#include <iostream>
#include <string>

// 1. 基本类定义
class Person {
private:    // 私有成员,类外不可访问
    std::string name;
    int age;
    
protected:  // 保护成员,派生类可访问
    std::string id;
    
public:     // 公有成员,类外可访问
    // 构造函数
    Person() : name("Unknown"), age(0), id("0000") {
        std::cout << "默认构造函数" << std::endl;
    }
    
    Person(const std::string& n, int a) : name(n), age(a) {
        id = generateId();
    }
    
    // 拷贝构造函数
    Person(const Person& other) : name(other.name), age(other.age), id(other.id) {
        std::cout << "拷贝构造函数" << std::endl;
    }
    
    // 移动构造函数(C++11)
    Person(Person&& other) noexcept 
        : name(std::move(other.name)), 
          age(other.age), 
          id(std::move(other.id)) {
        other.age = 0;
        std::cout << "移动构造函数" << std::endl;
    }
    
    // 析构函数
    ~Person() {
        std::cout << "析构函数: " << name << std::endl;
    }
    
    // 成员函数
    void introduce() const {
        std::cout << "我叫" << name << ", 今年" << age << "岁" << std::endl;
    }
    
    // 设置器和获取器
    void setName(const std::string& newName) { name = newName; }
    const std::string& getName() const { return name; }
    
    // 静态成员
    static int population;
    static std::string generateId() {
        return "ID_" + std::to_string(++population);
    }
    
    // 友元函数
    friend void printPrivateInfo(const Person& p);
    
    // 运算符重载
    Person& operator=(const Person& other) {
        if (this != &other) {
            name = other.name;
            age = other.age;
            id = other.id;
        }
        return *this;
    }
    
    bool operator==(const Person& other) const {
        return name == other.name && age == other.age;
    }
};

// 静态成员初始化
int Person::population = 0;

// 友元函数实现
void printPrivateInfo(const Person& p) {
    std::cout << "私有信息: " << p.name << ", " << p.age << std::endl;
}

// 2. 继承
class Student : public Person {
private:
    std::string studentId;
    double gpa;
    
public:
    // 使用基类构造函数
    using Person::Person;
    
    Student(const std::string& n, int a, const std::string& sid, double g) 
        : Person(n, a), studentId(sid), gpa(g) {}
    
    void study() {
        std::cout << getName() << "正在学习" << std::endl;
    }
    
    // 重写基类函数
    void introduce() const {
        Person::introduce();  // 调用基类版本
        std::cout << "我是学生,学号: " << studentId << std::endl;
    }
};

// 3. 多态与虚函数
class Animal {
public:
    // 虚函数
    virtual void speak() const {
        std::cout << "动物叫" << std::endl;
    }
    
    // 纯虚函数(抽象类)
    virtual void move() const = 0;
    
    // 虚析构函数(重要!)
    virtual ~Animal() {
        std::cout << "Animal析构" << std::endl;
    }
};

class Dog : public Animal {
public:
    void speak() const override {
        std::cout << "汪汪!" << std::endl;
    }
    
    void move() const override {
        std::cout << "用四条腿跑" << std::endl;
    }
    
    ~Dog() override {
        std::cout << "Dog析构" << std::endl;
    }
};

class Bird : public Animal {
public:
    void speak() const override final {  // final防止进一步重写
        std::cout << "叽叽喳喳" << std::endl;
    }
    
    void move() const override {
        std::cout << "用翅膀飞" << std::endl;
    }
};

int main() {
    // 对象创建
    Person p1("张三", 25);
    Person p2 = p1;            // 拷贝构造
    Person p3 = std::move(p1); // 移动构造
    
    // 多态演示
    Animal* animals[2];
    animals[0] = new Dog();
    animals[1] = new Bird();
    
    for (int i = 0; i < 2; i++) {
        animals[i]->speak();    // 动态绑定
        animals[i]->move();
        delete animals[i];      // 正确调用派生类析构函数
    }
    
    return 0;
}

2.2 现代C++特性:智能指针

cpp 复制代码
#include <memory>
#include <iostream>

class Resource {
public:
    Resource() { std::cout << "Resource创建" << std::endl; }
    ~Resource() { std::cout << "Resource销毁" << std::endl; }
    void use() { std::cout << "使用Resource" << std::endl; }
};

void demoSmartPointers() {
    std::cout << "\n=== 智能指针演示 ===" << std::endl;
    
    // 1. unique_ptr(独占所有权)
    {
        std::cout << "\n1. unique_ptr演示:" << std::endl;
        std::unique_ptr<Resource> up1(new Resource());
        auto up2 = std::make_unique<Resource>();  // 推荐方式(C++14)
        
        // 所有权转移
        std::unique_ptr<Resource> up3 = std::move(up1);
        
        // 自定义删除器
        auto deleter = [](Resource* ptr) {
            std::cout << "自定义删除器" << std::endl;
            delete ptr;
        };
        std::unique_ptr<Resource, decltype(deleter)> up4(new Resource(), deleter);
    }
    
    // 2. shared_ptr(共享所有权)
    {
        std::cout << "\n2. shared_ptr演示:" << std::endl;
        std::shared_ptr<Resource> sp1 = std::make_shared<Resource>();
        std::cout << "引用计数: " << sp1.use_count() << std::endl;
        
        {
            std::shared_ptr<Resource> sp2 = sp1;
            std::cout << "引用计数: " << sp1.use_count() << std::endl;
            
            std::shared_ptr<Resource> sp3 = sp2;
            std::cout << "引用计数: " << sp1.use_count() << std::endl;
        }
        std::cout << "引用计数: " << sp1.use_count() << std::endl;
        
        // 循环引用问题
        struct Node {
            std::shared_ptr<Node> next;
            ~Node() { std::cout << "Node销毁" << std::endl; }
        };
        
        auto node1 = std::make_shared<Node>();
        auto node2 = std::make_shared<Node>();
        node1->next = node2;
        node2->next = node1;  // 循环引用!内存泄漏
    }
    
    // 3. weak_ptr(弱引用)
    {
        std::cout << "\n3. weak_ptr演示:" << std::endl;
        std::shared_ptr<Resource> sp = std::make_shared<Resource>();
        std::weak_ptr<Resource> wp = sp;
        
        std::cout << "引用计数: " << sp.use_count() << std::endl;
        std::cout << "weak_ptr是否过期: " << wp.expired() << std::endl;
        
        if (auto locked = wp.lock()) {
            locked->use();
            std::cout << "成功获取shared_ptr" << std::endl;
        }
        
        sp.reset();  // 释放资源
        std::cout << "weak_ptr是否过期: " << wp.expired() << std::endl;
        
        // 解决循环引用
        struct SafeNode {
            std::weak_ptr<SafeNode> next;  // 使用weak_ptr
            ~SafeNode() { std::cout << "SafeNode销毁" << std::endl; }
        };
        
        auto safeNode1 = std::make_shared<SafeNode>();
        auto safeNode2 = std::make_shared<SafeNode>();
        safeNode1->next = safeNode2;
        safeNode2->next = safeNode1;  // 不会造成内存泄漏
    }
}

int main() {
    demoSmartPointers();
    return 0;
}

三、C++内存管理深度解析

3.1 内存分区模型

cpp 复制代码
#include <iostream>
#include <string>

// 全局变量 - 数据段
int globalVar = 100;           // 初始化的全局变量(.data段)
int uninitGlobalVar;           // 未初始化的全局变量(.bss段)
const int constGlobal = 200;   // 常量(只读数据段)

void memorySegments() {
    std::cout << "\n=== 内存分区演示 ===" << std::endl;
    
    // 1. 栈内存(Stack)
    int stackVar = 50;         // 栈上分配
    int array[100];            // 栈上数组(可能栈溢出)
    
    // 2. 堆内存(Heap)
    int* heapVar = new int(100);      // 堆上分配单个int
    int* heapArray = new int[1000];   // 堆上分配数组
    
    // 3. 字符串常量池
    const char* str1 = "Hello";       // 在常量池
    const char* str2 = "Hello";       // 相同字符串共享
    std::cout << "str1地址: " << (void*)str1 << std::endl;
    std::cout << "str2地址: " << (void*)str2 << std::endl;
    
    // 4. 验证栈和堆的地址差异
    std::cout << "\n栈变量地址: " << &stackVar << std::endl;
    std::cout << "堆变量地址: " << heapVar << std::endl;
    std::cout << "全局变量地址: " << &globalVar << std::endl;
    
    // 释放堆内存
    delete heapVar;
    delete[] heapArray;
}

// 演示栈帧
void functionA() {
    int a = 10;
    std::cout << "functionA - a地址: " << &a << std::endl;
}

void functionB() {
    int b = 20;
    std::cout << "functionB - b地址: " << &b << std::endl;
    functionA();
}

int main() {
    memorySegments();
    
    std::cout << "\n=== 栈帧演示 ===" << std::endl;
    int mainVar = 30;
    std::cout << "main - mainVar地址: " << &mainVar << std::endl;
    functionB();
    
    return 0;
}

3.2 内存对齐与布局

cpp 复制代码
#include <iostream>
#include <cstddef>

// 内存对齐示例
struct BadAlignment {
    char c;     // 1字节
    int i;      // 4字节(需要4字节对齐)
    short s;    // 2字节
    // 总大小:1 + 3(填充) + 4 + 2 = 10字节(但会补齐到12)
};

struct GoodAlignment {
    int i;      // 4字节
    short s;    // 2字节
    char c;     // 1字节
    // 总大小:4 + 2 + 1 + 1(填充) = 8字节
};

// 使用alignas指定对齐方式(C++11)
struct alignas(16) AlignedStruct {
    double data[2];  // 16字节对齐
};

// 使用alignof获取对齐要求(C++11)
void alignmentDemo() {
    std::cout << "\n=== 内存对齐演示 ===" << std::endl;
    
    std::cout << "BadAlignment大小: " << sizeof(BadAlignment) 
              << ", 对齐: " << alignof(BadAlignment) << std::endl;
    
    std::cout << "GoodAlignment大小: " << sizeof(GoodAlignment) 
              << ", 对齐: " << alignof(GoodAlignment) << std::endl;
    
    std::cout << "AlignedStruct大小: " << sizeof(AlignedStruct) 
              << ", 对齐: " << alignof(AlignedStruct) << std::endl;
    
    // 查看成员偏移量
    std::cout << "\nBadAlignment成员偏移:" << std::endl;
    std::cout << "c: " << offsetof(BadAlignment, c) << std::endl;
    std::cout << "i: " << offsetof(BadAlignment, i) << std::endl;
    std::cout << "s: " << offsetof(BadAlignment, s) << std::endl;
}

3.3 RAII(资源获取即初始化)

cpp 复制代码
#include <iostream>
#include <fstream>
#include <memory>
#include <mutex>

// 1. 文件资源的RAII包装
class FileHandle {
private:
    std::FILE* file;
    
public:
    explicit FileHandle(const char* filename, const char* mode = "r") 
        : file(std::fopen(filename, mode)) {
        if (!file) {
            throw std::runtime_error("无法打开文件");
        }
        std::cout << "文件打开: " << filename << std::endl;
    }
    
    ~FileHandle() {
        if (file) {
            std::fclose(file);
            std::cout << "文件关闭" << std::endl;
        }
    }
    
    // 禁止拷贝
    FileHandle(const FileHandle&) = delete;
    FileHandle& operator=(const FileHandle&) = delete;
    
    // 允许移动
    FileHandle(FileHandle&& other) noexcept : file(other.file) {
        other.file = nullptr;
    }
    
    FileHandle& operator=(FileHandle&& other) noexcept {
        if (this != &other) {
            if (file) std::fclose(file);
            file = other.file;
            other.file = nullptr;
        }
        return *this;
    }
    
    void write(const char* data) {
        if (file) std::fputs(data, file);
    }
};

// 2. 互斥锁的RAII包装
class ScopedLock {
private:
    std::mutex& mtx;
    
public:
    explicit ScopedLock(std::mutex& m) : mtx(m) {
        mtx.lock();
        std::cout << "锁已获取" << std::endl;
    }
    
    ~ScopedLock() {
        mtx.unlock();
        std::cout << "锁已释放" << std::endl;
    }
    
    // 禁止拷贝和移动
    ScopedLock(const ScopedLock&) = delete;
    ScopedLock& operator=(const ScopedLock&) = delete;
    ScopedLock(ScopedLock&&) = delete;
    ScopedLock& operator=(ScopedLock&&) = delete;
};

// 3. 自定义内存管理的RAII
template<typename T>
class MemoryPool {
private:
    T* pool;
    size_t capacity;
    
public:
    explicit MemoryPool(size_t size) : capacity(size) {
        pool = static_cast<T*>(std::malloc(size * sizeof(T)));
        if (!pool) {
            throw std::bad_alloc();
        }
        std::cout << "内存池分配: " << size * sizeof(T) << " 字节" << std::endl;
    }
    
    ~MemoryPool() {
        if (pool) {
            std::free(pool);
            std::cout << "内存池释放" << std::endl;
        }
    }
    
    T* allocate() {
        return pool;  // 简化实现
    }
};

void raiiDemo() {
    std::cout << "\n=== RAII演示 ===" << std::endl;
    
    // 文件处理 - 异常安全
    try {
        FileHandle file("test.txt", "w");
        file.write("Hello, RAII!\n");
        // 即使这里抛出异常,文件也会正确关闭
    } catch (const std::exception& e) {
        std::cout << "异常: " << e.what() << std::endl;
    }
    
    // 锁管理 - 防止死锁
    std::mutex mtx;
    {
        ScopedLock lock(mtx);
        // 临界区代码
        std::cout << "在临界区内操作" << std::endl;
    } // 离开作用域自动释放锁
    
    // 内存池
    {
        MemoryPool<int> pool(100);
        int* data = pool.allocate();
        // 使用data...
    } // 自动释放内存池
}

int main() {
    raiiDemo();
    return 0;
}

3.4 常见内存问题与调试

cpp 复制代码
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <new>

// 自定义new/delete操作符用于调试
void* operator new(size_t size) {
    void* ptr = std::malloc(size);
    std::cout << "分配内存: " << size << " 字节, 地址: " << ptr << std::endl;
    if (!ptr) throw std::bad_alloc();
    return ptr;
}

void operator delete(void* ptr) noexcept {
    std::cout << "释放内存, 地址: " << ptr << std::endl;
    std::free(ptr);
}

void memoryIssuesDemo() {
    std::cout << "\n=== 常见内存问题演示 ===" << std::endl;
    
    // 1. 内存泄漏
    void leakMemory() {
        int* leak = new int[100];
        // 忘记 delete[] leak;
    }
    
    // 2. 悬空指针
    void danglingPointer() {
        int* ptr = new int(42);
        delete ptr;
        // ptr现在是指向已释放内存的悬空指针
        // *ptr = 100; // 未定义行为!
    }
    
    // 3. 双重释放
    void doubleFree() {
        int* ptr = new int(42);
        delete ptr;
        // delete ptr; // 错误!再次释放同一内存
    }
    
    // 4. 缓冲区溢出
    void bufferOverflow() {
        char buffer[10];
        // strcpy(buffer, "这个字符串太长了"); // 缓冲区溢出
        std::strncpy(buffer, "安全拷贝", sizeof(buffer)-1);
        buffer[sizeof(buffer)-1] = '\0'; // 确保以null结尾
    }
    
    // 5. 使用未初始化内存
    void uninitializedMemory() {
        int x; // 未初始化
        // int y = x + 10; // 未定义行为
        int x2 = 0; // 总是初始化变量
    }
    
    // 6. 内存碎片化演示
    void memoryFragmentation() {
        std::cout << "\n内存碎片化演示:" << std::endl;
        
        // 分配和释放不同大小的内存块
        void* blocks[10];
        for (int i = 0; i < 10; i++) {
            blocks[i] = new char[10 * (i + 1)]; // 不同大小
        }
        
        // 随机释放一些块
        delete[] static_cast<char*>(blocks[2]);
        delete[] static_cast<char*>(blocks[5]);
        delete[] static_cast<char*>(blocks[8]);
        
        // 现在尝试分配一个大块
        try {
            char* largeBlock = new char[100]; // 可能失败,即使总空闲内存足够
            delete[] largeBlock;
        } catch (const std::bad_alloc&) {
            std::cout << "内存分配失败:碎片化问题" << std::endl;
        }
        
        // 清理
        for (int i = 0; i < 10; i++) {
            if (blocks[i]) {
                delete[] static_cast<char*>(blocks[i]);
            }
        }
    }
    
    memoryFragmentation();
}

// 内存调试工具
class MemoryDebugger {
private:
    static size_t totalAllocated;
    static size_t totalFreed;
    
public:
    static void* trackAlloc(size_t size, const char* file, int line) {
        void* ptr = malloc(size);
        totalAllocated += size;
        std::cout << file << ":" << line 
                  << " - 分配 " << size << " 字节, 总计: " 
                  << totalAllocated << std::endl;
        return ptr;
    }
    
    static void trackFree(void* ptr, size_t size, const char* file, int line) {
        totalFreed += size;
        std::cout << file << ":" << line 
                  << " - 释放 " << size << " 字节" << std::endl;
        
        if (totalAllocated == totalFreed) {
            std::cout << "所有内存已正确释放" << std::endl;
        } else {
            std::cout << "内存泄漏: " << (totalAllocated - totalFreed) 
                      << " 字节" << std::endl;
        }
    }
};

size_t MemoryDebugger::totalAllocated = 0;
size_t MemoryDebugger::totalFreed = 0;

// 重载new/delete进行跟踪
#define new new(__FILE__, __LINE__)
void* operator new(size_t size, const char* file, int line) {
    return MemoryDebugger::trackAlloc(size, file, line);
}

void operator delete(void* ptr, size_t size) noexcept {
    MemoryDebugger::trackFree(ptr, size, __FILE__, __LINE__);
    free(ptr);
}

int main() {
    memoryIssuesDemo();
    
    std::cout << "\n=== 内存调试演示 ===" << std::endl;
    int* debugPtr = new int(42);
    delete debugPtr;
    
    return 0;
}

四、在Android Framework中的应用

4.1 Android Native内存管理

cpp 复制代码
// Android中的内存管理实践
#include <android/log.h>
#include <utils/RefBase.h>  // Android的引用计数基类

#define LOG_TAG "NativeMemory"
#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)

// 1. Android智能指针使用
class NativeObject : public android::RefBase {
public:
    NativeObject() {
        ALOGD("NativeObject创建");
    }
    
    virtual ~NativeObject() {
        ALOGD("NativeObject销毁");
    }
    
    void doSomething() {
        ALOGD("NativeObject操作");
    }
};

// 2. 使用Android的sp/wp智能指针
void androidSmartPointerDemo() {
    ALOGD("=== Android智能指针演示 ===");
    
    // 强指针sp
    android::sp<NativeObject> strongPtr = new NativeObject();
    
    // 弱指针wp
    android::wp<NativeObject> weakPtr = strongPtr;
    
    // 提升弱指针
    android::sp<NativeObject> promoted = weakPtr.promote();
    if (promoted != nullptr) {
        ALOGD("成功提升弱指针");
        promoted->doSomething();
    }
    
    // 释放强指针
    strongPtr.clear();
    
    // 再次尝试提升
    promoted = weakPtr.promote();
    if (promoted == nullptr) {
        ALOGD("弱指针已过期");
    }
}

// 3. JNI中的内存管理
#include <jni.h>

extern "C" JNIEXPORT jlong JNICALL
Java_com_example_app_NativeLib_createNativeObject(JNIEnv* env, jobject thiz) {
    // 创建Native对象,返回指针给Java层
    NativeObject* obj = new NativeObject();
    return reinterpret_cast<jlong>(obj);
}

extern "C" JNIEXPORT void JNICALL
Java_com_example_app_NativeLib_useNativeObject(JNIEnv* env, jobject thiz, jlong ptr) {
    NativeObject* obj = reinterpret_cast<NativeObject*>(ptr);
    if (obj) {
        obj->doSomething();
    }
}

extern "C" JNIEXPORT void JNICALL
Java_com_example_app_NativeLib_destroyNativeObject(JNIEnv* env, jobject thiz, jlong ptr) {
    NativeObject* obj = reinterpret_cast<NativeObject*>(ptr);
    delete obj;
}

// 4. Android中的内存对齐
#include <cutils/align.h>

void androidAlignment() {
    void* ptr = malloc(100);
    
    // Android提供的对齐函数
    void* alignedPtr = (void*)ALIGN_UP((uintptr_t)ptr, 16);
    
    ALOGD("原始指针: %p, 对齐后: %p", ptr, alignedPtr);
    
    free(ptr);
}

// 5. Ashmem共享内存(Android特有)
#include <cutils/ashmem.h>

void sharedMemoryDemo() {
    int fd = ashmem_create_region("shared_memory", 4096);
    if (fd < 0) {
        ALOGD("创建共享内存失败");
        return;
    }
    
    // 设置保护模式
    ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
    
    // 映射到进程地址空间
    void* addr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (addr == MAP_FAILED) {
        ALOGD("内存映射失败");
        close(fd);
        return;
    }
    
    // 使用共享内存
    int* sharedData = static_cast<int*>(addr);
    *sharedData = 42;
    
    ALOGD("共享内存值: %d", *sharedData);
    
    // 清理
    munmap(addr, 4096);
    close(fd);
}

4.2 最佳实践与性能优化

cpp 复制代码
// C++内存管理最佳实践
class MemoryBestPractices {
public:
    // 1. 使用现代C++特性
    void modernCpp() {
        // 使用auto避免类型错误
        auto container = std::make_unique<std::vector<int>>();
        
        // 使用范围for循环
        for (const auto& item : *container) {
            // 处理item
        }
        
        // 使用智能指针管理所有权
        auto resource = std::make_shared<Resource>();
    }
    
    // 2. 避免不必要的拷贝
    void avoidCopies(const std::string& input) {  // 传递const引用
        // 使用移动语义
        std::string local = std::move(std::string(input)); // 示例
    }
    
    // 3. 使用reserve预分配内存
    void reserveMemory() {
        std::vector<int> numbers;
        numbers.reserve(1000);  // 预分配内存,避免多次重新分配
        
        for (int i = 0; i < 1000; i++) {
            numbers.push_back(i);
        }
    }
    
    // 4. 使用对象池
    class ObjectPool {
    private:
        struct PoolItem {
            void* memory;
            bool inUse;
        };
        std::vector<PoolItem> pool;
        
    public:
        void* allocate(size_t size) {
            for (auto& item : pool) {
                if (!item.inUse) {
                    item.inUse = true;
                    return item.memory;
                }
            }
            // 创建新项
            void* mem = malloc(size);
            pool.push_back({mem, true});
            return mem;
        }
        
        void deallocate(void* ptr) {
            for (auto& item : pool) {
                if (item.memory == ptr) {
                    item.inUse = false;
                    return;
                }
            }
        }
    };
    
    // 5. 对齐内存访问
    void alignedMemoryAccess() {
        // 使用对齐的内存分配
        alignas(64) int alignedArray[100];  // 64字节对齐,利于SIMD
        
        // 对于动态分配
        void* ptr = aligned_alloc(64, 1024);  // C++17
        if (ptr) {
            // 使用对齐的内存
            free(ptr);
        }
    }
    
    // 6. 使用内存映射文件处理大文件
    void memoryMappedFile(const char* filename) {
        // 在实际Android开发中,使用系统调用
        // int fd = open(filename, O_RDONLY);
        // void* addr = mmap(NULL, fileSize, PROT_READ, MAP_PRIVATE, fd, 0);
        // 处理文件内容...
        // munmap(addr, fileSize);
        // close(fd);
    }
};

五、调试工具与性能分析

5.1 内存调试工具使用

cpp 复制代码
// 内存调试技巧
#include <cassert>

void debuggingTechniques() {
    std::cout << "\n=== 内存调试技巧 ===" << std::endl;
    
    // 1. 使用assert进行运行时检查
    int* ptr = new int(42);
    assert(ptr != nullptr && "内存分配失败");
    
    // 2. 边界检查
    int array[10];
    int index = 5;
    assert(index >= 0 && index < 10 && "数组越界");
    array[index] = 100;
    
    // 3. 内存填充模式(调试时使用)
    #ifdef DEBUG
    constexpr unsigned char CLEAN_MEMORY = 0xCD;  // 已分配但未初始化
    constexpr unsigned char FREED_MEMORY = 0xDD;  // 已释放
    constexpr unsigned char GUARD_BYTE   = 0xFD;  // 边界保护
    
    void* debugPtr = malloc(100);
    memset(debugPtr, CLEAN_MEMORY, 100);  // 填充特定模式
    
    // 在边界添加保护字节
    unsigned char* guardedPtr = new unsigned char[100 + 2];
    guardedPtr[0] = GUARD_BYTE;
    guardedPtr[100 + 1] = GUARD_BYTE;
    
    // 检查保护字节是否被破坏
    if (guardedPtr[0] != GUARD_BYTE || guardedPtr[100 + 1] != GUARD_BYTE) {
        std::cout << "检测到内存破坏!" << std::endl;
    }
    #endif
    
    delete ptr;
}

// 自定义内存分配器用于调试
template<typename T>
class DebugAllocator {
public:
    using value_type = T;
    
    DebugAllocator() = default;
    
    template<typename U>
    DebugAllocator(const DebugAllocator<U>&) {}
    
    T* allocate(std::size_t n) {
        std::size_t totalSize = n * sizeof(T) + sizeof(std::size_t);
        void* ptr = malloc(totalSize);
        
        if (!ptr) throw std::bad_alloc();
        
        // 存储分配大小
        *static_cast<std::size_t*>(ptr) = n;
        
        // 返回分配的内存(跳过大小存储区)
        T* result = reinterpret_cast<T*>(
            static_cast<std::size_t*>(ptr) + 1);
        
        std::cout << "分配 " << n << " 个 " << typeid(T).name() 
                  << " 对象,总大小: " << totalSize << std::endl;
        
        return result;
    }
    
    void deallocate(T* ptr, std::size_t n) noexcept {
        // 获取原始指针(包含大小信息)
        void* originalPtr = static_cast<void*>(
            static_cast<std::size_t*>(ptr) - 1);
        
        // 读取分配时的大小
        std::size_t allocatedSize = *static_cast<std::size_t*>(originalPtr);
        
        if (allocatedSize != n) {
            std::cout << "警告:分配大小(" << allocatedSize 
                      << ")与释放大小(" << n << ")不匹配" << std::endl;
        }
        
        std::cout << "释放 " << n << " 个 " << typeid(T).name() 
                  << " 对象" << std::endl;
        
        free(originalPtr);
    }
};

六、学习建议

6.1 学习路径规划

markdown 复制代码
第一阶段(1-2个月):基础语法
    ├── 基本数据类型与运算符
    ├── 控制结构(循环、条件)
    ├── 函数与作用域
    ├── 数组与字符串
    └── 结构体与类基础

第二阶段(2-3个月):面向对象与内存
    ├── 类与对象深入
    ├── 继承与多态
    ├── 内存管理基础
    ├── 指针与引用
    └── 基本模板编程

第三阶段(3-4个月):现代C++与实战
    ├── 智能指针与RAII
    ├── 移动语义与右值引用
    ├── STL容器与算法
    ├── Lambda表达式
    └── 并发编程基础

第四阶段(持续):深入Android Framework
    ├── Android Native开发
    ├── JNI编程
    ├── Android智能指针
    └── Framework源码分析

6.2 实践项目建议

  1. 基础项目:实现一个简单的字符串类(带拷贝控制)
  2. 中级项目:实现一个智能指针模板类
  3. 高级项目:实现一个简单的对象池内存管理器
  4. Android项目:编写JNI代码,实现Java与C++的数据交换

6.3 重要习惯养成

  1. 内存安全第一:始终使用智能指针,除非有特殊需求
  2. RAII原则:资源获取即初始化,利用对象生命周期管理资源
  3. 避免裸指针:尽量减少使用原始指针
  4. 性能意识:了解内存对齐、缓存友好性等概念
  5. 调试技巧:学会使用Valgrind、AddressSanitizer等工具

七、常见面试题

Q1:new/delete和malloc/free的区别?

答案

  1. 类型安全:new返回具体类型指针,malloc返回void*
  2. 构造/析构:new调用构造函数,delete调用析构函数
  3. 内存大小:new自动计算大小,malloc需要手动指定
  4. 异常处理:new分配失败抛异常,malloc返回nullptr
  5. 重载能力:new/delete可以重载,malloc/free不能
  6. 内存来源:new从自由存储区分配,malloc从堆分配

Q2:什么是内存泄漏?如何检测和避免?

答案内存泄漏:已分配的内存无法被访问且无法被释放。

检测方法

  1. 使用工具:Valgrind、AddressSanitizer、Visual Studio诊断工具
  2. 重载new/delete记录分配和释放
  3. 使用智能指针进行自动管理

避免方法

  1. 使用RAII模式
  2. 优先使用智能指针
  3. 遵循谁分配谁释放的原则
  4. 使用容器类而不是原始数组

Q3:C++11的移动语义有什么作用?

答案

  1. 避免不必要的拷贝:通过移动而非拷贝转移资源
  2. 提高性能:移动操作通常比拷贝快得多
  3. 实现完美转发:保持参数的值类别(左值/右值)
  4. 支持不可拷贝类型的转移:如unique_ptr
cpp 复制代码
// 示例:移动构造 vs 拷贝构造
class Resource {
    int* data;
public:
    // 移动构造函数
    Resource(Resource&& other) noexcept : data(other.data) {
        other.data = nullptr;  // 转移所有权
    }
    
    // 拷贝构造函数
    Resource(const Resource& other) {
        data = new int[100];
        std::copy(other.data, other.data + 100, data);  // 深拷贝
    }
};

总结

C++内存管理是系统级开发的核心技能,特别是对于Android Framework开发。关键点:

  1. 理解内存分区:栈、堆、全局区、常量区
  2. 掌握智能指针:unique_ptr、shared_ptr、weak_ptr
  3. 实践RAII原则:利用对象生命周期管理资源
  4. 熟悉现代C++:移动语义、Lambda、auto等特性
  5. 学习Android特定实践:sp/wp智能指针、JNI内存管理

在学习过程中,要边学边练,通过实际项目加深理解。Framework开发需要扎实的C++基础,但更重要的是工程实践能力和调试技巧。

相关推荐
陈希瑞2 小时前
【保姆级教程】安卓手机免Root一键部署AutoGLM:支持语音控制与自动化操作
android·智能手机·自动化
TheNextByte12 小时前
如何将联系人从Android传输到计算机的 6 种方法
android
喂_balabala2 小时前
excludeFromRecents
android
TimeFine2 小时前
Android AI解放生产力(五)实战:解放写API接口的繁琐工作
android
csj504 小时前
安卓基础之《(6)—Activity组件(3)》
android
怀旧,5 小时前
【Linux系统编程】13. Ext系列⽂件系统
android·linux·缓存
Dabei5 小时前
Android 语音助手简单实现与语音助手“执行任务”交流
android·前端
jzlhll1235 小时前
android NDSDManager onResolveFailed errorCode=3的解决方案
android
芦半山5 小时前
四年之后,重新审视 MTE:从硬件架构到工程落地
android·安全