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 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台2 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone2 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc2 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo2 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077002 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone3 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen3 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone3 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui