C++ 入门完全指南(六)--指针与动态内存

文章目录

    • [第10章 指针基础](#第10章 指针基础)
      • [10.1 内存地址与指针概念](#10.1 内存地址与指针概念)
        • [10.1.1 理解内存地址](#10.1.1 理解内存地址)
        • [10.1.2 指针的基本概念](#10.1.2 指针的基本概念)
      • [10.2 指针与数组](#10.2 指针与数组)
        • [10.2.1 指针与一维数组](#10.2.1 指针与一维数组)
        • [10.2.2 指针与多维数组](#10.2.2 指针与多维数组)
      • [10.3 指针与字符串](#10.3 指针与字符串)
        • [10.3.1 C风格字符串操作](#10.3.1 C风格字符串操作)
      • [10.4 函数指针](#10.4 函数指针)
        • [10.4.1 函数指针基础](#10.4.1 函数指针基础)
      • [10.5 动态内存管理](#10.5 动态内存管理)
        • [10.5.1 new和delete操作符](#10.5.1 new和delete操作符)
        • [10.5.2 动态内存管理的最佳实践](#10.5.2 动态内存管理的最佳实践)
      • [10.6 实践练习](#10.6 实践练习)

第10章 指针基础

10.1 内存地址与指针概念

10.1.1 理解内存地址
cpp 复制代码
#include <iostream>
using namespace std;

void demonstrateMemoryAddress() {
    cout << "=== 内存地址与指针概念 ===" << endl;
    
    // 1. 变量的内存地址
    int num = 42;
    char ch = 'A';
    double pi = 3.14159;
    
    cout << "变量值及其内存地址:" << endl;
    cout << "num = " << num << ", 地址: " << &num << endl;
    cout << "ch = '" << ch << "', 地址: " << (void*)&ch << endl;  // 需要类型转换
    cout << "pi = " << pi << ", 地址: " << &pi << endl;
    
    // 2. 内存地址的特性
    cout << "\n内存地址的特性:" << endl;
    
    int arr[3] = {10, 20, 30};
    cout << "数组元素地址:" << endl;
    for (int i = 0; i < 3; i++) {
        cout << "arr[" << i << "] = " << arr[i] 
             << ", 地址: " << &arr[i] << endl;
    }
    
    // 相邻元素的地址差 = 类型大小
    cout << "地址差: " << (char*)&arr[1] - (char*)&arr[0] 
         << " 字节 (int类型大小: " << sizeof(int) << " 字节)" << endl;
    
    // 3. 结构体的内存布局
    struct Student {
        int id;
        double score;
        char grade;
    };
    
    Student s = {1001, 95.5, 'A'};
    cout << "\n结构体内存地址:" << endl;
    cout << "s.id = " << s.id << ", 地址: " << &s.id << endl;
    cout << "s.score = " << s.score << ", 地址: " << &s.score << endl;
    cout << "s.grade = '" << s.grade << "', 地址: " << (void*)&s.grade << endl;
    
    // 结构体总大小
    cout << "结构体总大小: " << sizeof(Student) << " 字节" << endl;
    cout << "可能存在内存对齐(padding)" << endl;
    
    // 4. 指针的大小
    cout << "\n指针的大小(与平台相关):" << endl;
    cout << "int* 大小: " << sizeof(int*) << " 字节" << endl;
    cout << "char* 大小: " << sizeof(char*) << " 字节" << endl;
    cout << "double* 大小: " << sizeof(double*) << " 字节" << endl;
    cout << "void* 大小: " << sizeof(void*) << " 字节" << endl;
    
    // 5. 不同平台的指针大小
    cout << "\n不同平台的典型指针大小:" << endl;
    cout << "32位系统: 4 字节" << endl;
    cout << "64位系统: 8 字节" << endl;
    cout << "当前系统: " << sizeof(void*) * 8 << " 位" << endl;
}

void demonstrateEndianness() {
    cout << "\n=== 字节序(Endianness)===" << endl;
    
    // 测试系统字节序
    int test = 0x12345678;
    unsigned char* bytes = (unsigned char*)&test;
    
    cout << "整数 0x12345678 在内存中的存储:" << endl;
    cout << "地址: " << &test << endl;
    
    cout << "字节顺序: ";
    for (int i = 0; i < sizeof(int); i++) {
        printf("%p: 0x%02X\n", (void*)(bytes + i), bytes[i]);
    }
    
    if (bytes[0] == 0x78) {
        cout << "小端序 (Little Endian): 低位字节在前" << endl;
    } else if (bytes[0] == 0x12) {
        cout << "大端序 (Big Endian): 高位字节在前" << endl;
    }
    
    // 字节序的影响
    union EndianTest {
        int num;
        char bytes[4];
    };
    
    EndianTest et;
    et.num = 0x12345678;
    
    cout << "\n通过union测试:" << endl;
    if (et.bytes[0] == 0x78) {
        cout << "小端序系统" << endl;
    } else {
        cout << "大端序系统" << endl;
    }
}

int main() {
    demonstrateMemoryAddress();
    demonstrateEndianness();
    
    return 0;
}
10.1.2 指针的基本概念
cpp 复制代码
#include <iostream>
using namespace std;

void demonstrateBasicPointers() {
    cout << "=== 指针的基本概念 ===" << endl;
    
    // 1. 指针的声明和初始化
    cout << "1. 指针的声明和初始化:" << endl;
    
    int num = 100;
    int* ptr;           // 声明指针(未初始化)
    ptr = &num;         // 初始化指针,指向num的地址
    
    cout << "num = " << num << endl;
    cout << "&num = " << &num << endl;
    cout << "ptr = " << ptr << " (存储的地址)" << endl;
    cout << "*ptr = " << *ptr << " (解引用)" << endl;
    
    // 2. 不同类型的指针
    cout << "\n2. 不同类型的指针:" << endl;
    
    char ch = 'X';
    double value = 3.14;
    bool flag = true;
    
    char* charPtr = &ch;
    double* doublePtr = &value;
    bool* boolPtr = &flag;
    
    cout << "char指针: " << (void*)charPtr << ", 值: " << *charPtr << endl;
    cout << "double指针: " << doublePtr << ", 值: " << *doublePtr << endl;
    cout << "bool指针: " << boolPtr << ", 值: " << *boolPtr << endl;
    
    // 3. void指针(通用指针)
    cout << "\n3. void指针(通用指针):" << endl;
    
    void* voidPtr = &num;  // 可以指向任何类型
    cout << "voidPtr指向int: " << voidPtr << endl;
    
    voidPtr = &ch;        // 现在指向char
    cout << "voidPtr指向char: " << voidPtr << endl;
    
    // void指针不能直接解引用
    // cout << *voidPtr << endl;  // 错误
    
    // 需要类型转换后才能使用
    cout << "通过类型转换解引用: " << *(char*)voidPtr << endl;
    
    // 4. 空指针
    cout << "\n4. 空指针 (nullptr):" << endl;
    
    int* nullPtr = nullptr;  // C++11 空指针字面量
    int* oldNull = NULL;     // 传统方式(C风格)
    int* zeroNull = 0;       // 不推荐
    
    cout << "nullptr: " << nullPtr << endl;
    cout << "NULL: " << oldNull << endl;
    cout << "0: " << zeroNull << endl;
    
    // 检查指针是否为空
    if (nullPtr == nullptr) {
        cout << "指针为空" << endl;
    }
    
    // 5. 野指针和悬垂指针
    cout << "\n5. 野指针和悬垂指针(危险!):" << endl;
    
    // 野指针:未初始化的指针
    int* wildPtr;  // 野指针,值不确定
    // cout << *wildPtr << endl;  // 未定义行为
    
    // 悬垂指针:指向已释放内存的指针
    int* danglingPtr = new int(999);
    cout << "分配内存,值: " << *danglingPtr << endl;
    
    delete danglingPtr;  // 释放内存
    danglingPtr = nullptr;  // 好习惯:立即设为空指针
    
    // 现在danglingPtr是悬垂指针
    // cout << *danglingPtr << endl;  // 未定义行为
    
    // 6. 常量指针 vs 指针常量
    cout << "\n6. 常量指针与指针常量:" << endl;
    
    int a = 10, b = 20;
    
    // 指针常量:指针本身是常量(不能改变指向)
    int* const ptrConst = &a;
    cout << "指针常量: ptrConst = " << ptrConst << ", *ptrConst = " << *ptrConst << endl;
    *ptrConst = 30;      // 可以修改指向的值
    // ptrConst = &b;    // 错误:不能改变指向
    
    // 常量指针:指向常量的指针(不能修改值)
    const int* constPtr = &a;
    cout << "常量指针: constPtr = " << constPtr << ", *constPtr = " << *constPtr << endl;
    // *constPtr = 40;   // 错误:不能修改值
    constPtr = &b;       // 可以改变指向
    
    // 常量指针常量:都不能修改
    const int* const constPtrConst = &a;
    // *constPtrConst = 50;  // 错误
    // constPtrConst = &b;   // 错误
}

void demonstratePointerArithmetic() {
    cout << "\n=== 指针算术运算 ===" << endl;
    
    // 1. 指针加减整数
    int arr[5] = {10, 20, 30, 40, 50};
    int* ptr = arr;  // 指向数组第一个元素
    
    cout << "数组地址: " << arr << endl;
    cout << "ptr = " << ptr << endl;
    
    cout << "\n指针加法:" << endl;
    for (int i = 0; i < 5; i++) {
        cout << "ptr + " << i << " = " << (ptr + i)
             << ", *(ptr + " << i << ") = " << *(ptr + i) << endl;
    }
    
    cout << "\n指针减法:" << endl;
    int* endPtr = ptr + 4;
    for (int i = 4; i >= 0; i--) {
        cout << "endPtr - " << (4 - i) << " = " << (endPtr - (4 - i))
             << ", 值 = " << *(endPtr - (4 - i)) << endl;
    }
    
    // 2. 指针相减(得到元素个数)
    cout << "\n指针相减(计算距离):" << endl;
    int* ptr1 = &arr[0];
    int* ptr2 = &arr[3];
    
    ptrdiff_t distance = ptr2 - ptr1;
    cout << "ptr2 - ptr1 = " << distance << " 个元素" << endl;
    cout << "实际字节距离: " << (char*)ptr2 - (char*)ptr1 << " 字节" << endl;
    
    // 3. 指针比较
    cout << "\n指针比较:" << endl;
    cout << "ptr1 < ptr2? " << (ptr1 < ptr2) << endl;
    cout << "ptr1 > ptr2? " << (ptr1 > ptr2) << endl;
    cout << "ptr1 == ptr1? " << (ptr1 == ptr1) << endl;
    
    // 4. void指针的算术运算限制
    cout << "\nvoid指针算术运算限制:" << endl;
    void* voidPtr = arr;
    // voidPtr++;  // 错误:void指针不知道类型大小
    // voidPtr = voidPtr + 1;  // 错误
    
    // 需要转换为具体类型
    voidPtr = (char*)voidPtr + sizeof(int);  // 正确
    cout << "voidPtr移动一个int大小后: " << voidPtr << endl;
}

int main() {
    demonstrateBasicPointers();
    demonstratePointerArithmetic();
    
    return 0;
}

10.2 指针与数组

10.2.1 指针与一维数组
cpp 复制代码
#include <iostream>
using namespace std;

void demonstratePointersAndArrays() {
    cout << "=== 指针与一维数组 ===" << endl;
    
    // 1. 数组名作为指针
    int arr[5] = {10, 20, 30, 40, 50};
    
    cout << "数组元素:" << endl;
    for (int i = 0; i < 5; i++) {
        cout << "arr[" << i << "] = " << arr[i] << endl;
    }
    
    cout << "\n数组名的本质:" << endl;
    cout << "arr = " << arr << " (数组首地址)" << endl;
    cout << "&arr[0] = " << &arr[0] << " (第一个元素地址)" << endl;
    cout << "arr == &arr[0]? " << (arr == &arr[0]) << endl;
    
    // 2. 使用指针遍历数组
    cout << "\n2. 使用指针遍历数组:" << endl;
    
    // 方法1:指针作为迭代器
    int* ptr = arr;
    cout << "使用指针遍历: ";
    for (int i = 0; i < 5; i++) {
        cout << *ptr << " ";
        ptr++;  // 移动到下一个元素
    }
    cout << endl;
    
    // 方法2:指针算术运算
    cout << "使用指针算术: ";
    for (int i = 0; i < 5; i++) {
        cout << *(arr + i) << " ";
    }
    cout << endl;
    
    // 3. 数组指针 vs 指针数组
    cout << "\n3. 数组指针与指针数组:" << endl;
    
    // 数组指针:指向整个数组的指针
    int (*arrayPtr)[5] = &arr;  // 指向包含5个int的数组
    
    cout << "数组指针 arrayPtr = " << arrayPtr << endl;
    cout << "*arrayPtr = " << *arrayPtr << " (等价于arr)" << endl;
    cout << "(*arrayPtr)[2] = " << (*arrayPtr)[2] << endl;
    
    // 指针数组:元素都是指针的数组
    int x = 1, y = 2, z = 3;
    int* ptrArray[3] = {&x, &y, &z};
    
    cout << "\n指针数组元素:" << endl;
    for (int i = 0; i < 3; i++) {
        cout << "ptrArray[" << i << "] = " << ptrArray[i]
             << ", *ptrArray[" << i << "] = " << *ptrArray[i] << endl;
    }
    
    // 4. 数组作为函数参数(退化为指针)
    cout << "\n4. 数组作为函数参数:" << endl;
    
    auto printArray = [](int* arr, int size) {
        cout << "在函数中: sizeof(arr) = " << sizeof(arr) << " (指针大小)" << endl;
        cout << "数组元素: ";
        for (int i = 0; i < size; i++) {
            cout << arr[i] << " ";
        }
        cout << endl;
    };
    
    cout << "在main中: sizeof(arr) = " << sizeof(arr) << " (数组总大小)" << endl;
    printArray(arr, 5);
    
    // 5. 指针和多维数组
    cout << "\n5. 指针和多维数组:" << endl;
    
    int matrix[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };
    
    // 指向一维数组的指针
    int (*rowPtr)[4] = matrix;  // 指向包含4个int的数组
    
    cout << "使用数组指针访问多维数组:" << endl;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            cout << rowPtr[i][j] << "\t";
        }
        cout << endl;
    }
}

void demonstrateArrayDecay() {
    cout << "\n=== 数组退化(Array Decay)===" << endl;
    
    // 数组退化为指针的各种情况
    int arr[5] = {1, 2, 3, 4, 5};
    
    cout << "1. 赋值给指针:" << endl;
    int* ptr = arr;  // 数组退化为指针
    cout << "ptr = arr;  // 数组名退化为指针" << endl;
    
    cout << "\n2. 作为函数参数:" << endl;
    cout << "void func(int arr[]) 等价于 void func(int* arr)" << endl;
    
    cout << "\n3. 与指针比较:" << endl;
    if (arr == &arr[0]) {
        cout << "arr == &arr[0] 为真" << endl;
    }
    
    cout << "\n4. 但有几个例外(不会退化):" << endl;
    cout << "a) sizeof(arr) = " << sizeof(arr) << " (得到数组总大小)" << endl;
    cout << "b) &arr = " << &arr << " (得到整个数组的地址)" << endl;
    
    // 整个数组的地址 vs 第一个元素的地址
    cout << "\n整个数组地址与第一个元素地址:" << endl;
    cout << "arr = " << arr << endl;
    cout << "&arr = " << &arr << endl;
    cout << "arr + 1 = " << arr + 1 << " (移动4字节)" << endl;
    cout << "&arr + 1 = " << &arr + 1 << " (移动" << sizeof(arr) << "字节)" << endl;
    
    // 类型不同
    cout << "\n类型信息:" << endl;
    cout << "typeid(arr).name() = " << typeid(arr).name() << endl;
    cout << "typeid(&arr).name() = " << typeid(&arr).name() << endl;
}

// 字符串与指针
void demonstrateStringsAndPointers() {
    cout << "\n=== 字符串与指针 ===" << endl;
    
    // 1. C风格字符串
    char str1[] = "Hello";          // 字符数组
    const char* str2 = "World";     // 字符串字面量(只读)
    
    cout << "字符数组: " << str1 << endl;
    cout << "字符串指针: " << str2 << endl;
    
    cout << "\n内存布局:" << endl;
    cout << "str1地址: " << (void*)str1 << endl;
    cout << "str2地址: " << (void*)str2 << endl;
    cout << "str2指向的内容地址: " << (void*)str2 << endl;
    
    // 2. 修改字符串
    str1[0] = 'h';  // 可以修改,因为str1是数组
    // str2[0] = 'w';  // 错误:字符串字面量是只读的
    
    cout << "\n修改后:" << endl;
    cout << "str1: " << str1 << endl;
    
    // 3. 字符串数组
    const char* colors[] = {
        "Red",
        "Green",
        "Blue",
        "Yellow",
        "Purple"
    };
    
    cout << "\n字符串数组(实际上是指针数组):" << endl;
    for (int i = 0; i < 5; i++) {
        cout << colors[i] << " ";
    }
    cout << endl;
    
    // 4. 字符串长度
    cout << "\n字符串长度计算:" << endl;
    
    const char* message = "C++ Programming";
    int length = 0;
    const char* p = message;
    
    while (*p != '\0') {
        length++;
        p++;
    }
    
    cout << "字符串: " << message << endl;
    cout << "长度: " << length << endl;
    cout << "使用strlen: " << strlen(message) << endl;
    
    // 5. 字符串复制
    char source[] = "Copy this";
    char destination[20];
    
    char* destPtr = destination;
    const char* srcPtr = source;
    
    while (*srcPtr != '\0') {
        *destPtr = *srcPtr;
        destPtr++;
        srcPtr++;
    }
    *destPtr = '\0';  // 添加终止符
    
    cout << "\n字符串复制:" << endl;
    cout << "源: " << source << endl;
    cout << "目标: " << destination << endl;
}

int main() {
    demonstratePointersAndArrays();
    demonstrateArrayDecay();
    demonstrateStringsAndPointers();
    
    return 0;
}
10.2.2 指针与多维数组
cpp 复制代码
#include <iostream>
#include <iomanip>
using namespace std;

void demonstrateMultidimensionalPointers() {
    cout << "=== 指针与多维数组 ===" << endl;
    
    // 1. 二维数组的内存布局
    cout << "1. 二维数组的内存布局:" << endl;
    
    int matrix[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };
    
    cout << "3x4矩阵:" << endl;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            cout << setw(4) << matrix[i][j];
        }
        cout << endl;
    }
    
    // 2. 二维数组在内存中是连续的
    cout << "\n2. 内存连续性验证:" << endl;
    
    int* flat = &matrix[0][0];  // 指向第一个元素
    cout << "以一维数组方式访问:" << endl;
    for (int i = 0; i < 12; i++) {
        cout << flat[i] << " ";
        if ((i + 1) % 4 == 0) cout << endl;
    }
    
    // 3. 指向一维数组的指针
    cout << "\n3. 指向一维数组的指针:" << endl;
    
    // 声明指向包含4个int的数组的指针
    int (*rowPtr)[4] = matrix;
    
    cout << "rowPtr指向包含4个int的数组" << endl;
    cout << "rowPtr = " << rowPtr << endl;
    cout << "rowPtr + 1 = " << rowPtr + 1 << " (移动一行)" << endl;
    cout << "移动字节数: " << (char*)(rowPtr + 1) - (char*)rowPtr << endl;
    
    // 使用这种指针访问数组
    cout << "\n使用rowPtr访问:" << endl;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            cout << setw(4) << rowPtr[i][j];
        }
        cout << endl;
    }
    
    // 4. 指针数组模拟二维数组
    cout << "\n4. 指针数组模拟二维数组:" << endl;
    
    int row1[4] = {1, 2, 3, 4};
    int row2[4] = {5, 6, 7, 8};
    int row3[4] = {9, 10, 11, 12};
    
    int* ptrArray[3] = {row1, row2, row3};  // 指针数组
    
    cout << "指针数组访问:" << endl;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            cout << setw(4) << ptrArray[i][j];
        }
        cout << endl;
    }
    
    // 5. 动态二维数组
    cout << "\n5. 动态二维数组:" << endl;
    
    int rows = 3, cols = 4;
    
    // 方法1:使用指针数组
    int** dynamicMatrix = new int*[rows];
    for (int i = 0; i < rows; i++) {
        dynamicMatrix[i] = new int[cols];
    }
    
    // 初始化
    int counter = 1;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            dynamicMatrix[i][j] = counter++;
        }
    }
    
    cout << "动态二维数组:" << endl;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            cout << setw(4) << dynamicMatrix[i][j];
        }
        cout << endl;
    }
    
    // 释放内存
    for (int i = 0; i < rows; i++) {
        delete[] dynamicMatrix[i];
    }
    delete[] dynamicMatrix;
    
    // 方法2:使用一维数组模拟
    cout << "\n6. 使用一维数组模拟二维数组:" << endl;
    
    int* flatMatrix = new int[rows * cols];
    
    // 初始化
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            flatMatrix[i * cols + j] = i * cols + j + 1;
        }
    }
    
    cout << "扁平化矩阵:" << endl;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            cout << setw(4) << flatMatrix[i * cols + j];
        }
        cout << endl;
    }
    
    delete[] flatMatrix;
}

// 三维数组与指针
void demonstrate3DArraysAndPointers() {
    cout << "\n=== 三维数组与指针 ===" << endl;
    
    // 1. 静态三维数组
    int cube[2][3][4] = {
        {   // 第一层
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12}
        },
        {   // 第二层
            {13, 14, 15, 16},
            {17, 18, 19, 20},
            {21, 22, 23, 24}
        }
    };
    
    // 2. 指向二维数组的指针
    int (*layerPtr)[3][4] = cube;  // 指向包含3x4个int的二维数组
    
    cout << "使用指针访问三维数组:" << endl;
    for (int i = 0; i < 2; i++) {
        cout << "第 " << i << " 层:" << endl;
        for (int j = 0; j < 3; j++) {
            for (int k = 0; k < 4; k++) {
                cout << setw(4) << layerPtr[i][j][k];
            }
            cout << endl;
        }
        cout << endl;
    }
    
    // 3. 三维数组的内存布局
    cout << "三维数组的内存连续性验证:" << endl;
    int* flat = &cube[0][0][0];
    
    cout << "连续内存访问:" << endl;
    for (int i = 0; i < 24; i++) {
        cout << flat[i] << " ";
        if ((i + 1) % 4 == 0) cout << "  ";
        if ((i + 1) % 12 == 0) cout << endl;
    }
    
    // 4. 动态三维数组
    cout << "\n动态三维数组:" << endl;
    
    int x = 2, y = 3, z = 4;
    
    // 分配三维数组
    int*** dynamicCube = new int**[x];
    for (int i = 0; i < x; i++) {
        dynamicCube[i] = new int*[y];
        for (int j = 0; j < y; j++) {
            dynamicCube[i][j] = new int[z];
        }
    }
    
    // 初始化
    int count = 1;
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
            for (int k = 0; k < z; k++) {
                dynamicCube[i][j][k] = count++;
            }
        }
    }
    
    // 显示
    for (int i = 0; i < x; i++) {
        cout << "第 " << i << " 层:" << endl;
        for (int j = 0; j < y; j++) {
            for (int k = 0; k < z; k++) {
                cout << setw(4) << dynamicCube[i][j][k];
            }
            cout << endl;
        }
        cout << endl;
    }
    
    // 释放内存(必须按分配顺序的逆序)
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
            delete[] dynamicCube[i][j];
        }
        delete[] dynamicCube[i];
    }
    delete[] dynamicCube;
}

// 数组指针与函数参数
void demonstrateArrayPointersAsParameters() {
    cout << "\n=== 数组指针作为函数参数 ===" << endl;
    
    // 1. 传递一维数组
    auto print1DArray = [](int* arr, int size) {
        cout << "一维数组: ";
        for (int i = 0; i < size; i++) {
            cout << arr[i] << " ";
        }
        cout << endl;
    };
    
    int arr1D[5] = {1, 2, 3, 4, 5};
    print1DArray(arr1D, 5);
    
    // 2. 传递二维数组(必须指定列数)
    auto print2DArray = [](int arr[][4], int rows) {
        cout << "二维数组 (" << rows << "x4):" << endl;
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < 4; j++) {
                cout << setw(4) << arr[i][j];
            }
            cout << endl;
        }
    };
    
    int arr2D[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };
    
    print2DArray(arr2D, 3);
    
    // 3. 使用指针传递二维数组
    auto print2DArrayWithPointer = [](int (*arr)[4], int rows) {
        cout << "使用数组指针传递:" << endl;
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < 4; j++) {
                cout << setw(4) << arr[i][j];
            }
            cout << endl;
        }
    };
    
    print2DArrayWithPointer(arr2D, 3);
    
    // 4. 传递动态二维数组
    auto printDynamic2DArray = [](int** arr, int rows, int cols) {
        cout << "动态二维数组 (" << rows << "x" << cols << "):" << endl;
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                cout << setw(4) << arr[i][j];
            }
            cout << endl;
        }
    };
    
    // 创建动态二维数组
    int rows = 3, cols = 4;
    int** dynamicArr = new int*[rows];
    for (int i = 0; i < rows; i++) {
        dynamicArr[i] = new int[cols];
        for (int j = 0; j < cols; j++) {
            dynamicArr[i][j] = i * cols + j + 1;
        }
    }
    
    printDynamic2DArray(dynamicArr, rows, cols);
    
    // 清理
    for (int i = 0; i < rows; i++) {
        delete[] dynamicArr[i];
    }
    delete[] dynamicArr;
}

int main() {
    demonstrateMultidimensionalPointers();
    demonstrate3DArraysAndPointers();
    demonstrateArrayPointersAsParameters();
    
    return 0;
}

10.3 指针与字符串

10.3.1 C风格字符串操作
cpp 复制代码
#include <iostream>
#include <cstring>  // C字符串函数
#include <cctype>   // 字符处理
using namespace std;

void demonstrateCStringOperations() {
    cout << "=== C风格字符串操作 ===" << endl;
    
    // 1. 字符串声明和初始化
    cout << "1. 字符串声明和初始化:" << endl;
    
    char str1[] = "Hello";           // 字符数组
    char str2[10] = "World";         // 指定大小的数组
    char str3[] = {'H', 'i', '\0'};  // 手动添加终止符
    const char* str4 = "C++";        // 字符串字面量(常量)
    
    cout << "str1: " << str1 << endl;
    cout << "str2: " << str2 << endl;
    cout << "str3: " << str3 << endl;
    cout << "str4: " << str4 << endl;
    
    // 2. 字符串长度
    cout << "\n2. 字符串长度:" << endl;
    
    const char* text = "Programming";
    cout << "字符串: " << text << endl;
    cout << "strlen: " << strlen(text) << endl;
    
    // 手动计算长度
    int length = 0;
    const char* p = text;
    while (*p != '\0') {
        length++;
        p++;
    }
    cout << "手动计算: " << length << endl;
    
    // 3. 字符串复制
    cout << "\n3. 字符串复制:" << endl;
    
    char source[] = "Copy this text";
    char dest1[20];
    char dest2[20];
    
    // 使用strcpy
    strcpy(dest1, source);
    cout << "strcpy: " << dest1 << endl;
    
    // 使用strncpy(安全版本)
    strncpy(dest2, source, sizeof(dest2) - 1);
    dest2[sizeof(dest2) - 1] = '\0';  // 确保终止符
    cout << "strncpy: " << dest2 << endl;
    
    // 4. 字符串连接
    cout << "\n4. 字符串连接:" << endl;
    
    char greeting[50] = "Hello";
    char name[] = " Alice";
    
    strcat(greeting, name);
    cout << "strcat: " << greeting << endl;
    
    // 安全版本
    char safeGreeting[20] = "Hello";
    strncat(safeGreeting, " World!", sizeof(safeGreeting) - strlen(safeGreeting) - 1);
    cout << "strncat: " << safeGreeting << endl;
    
    // 5. 字符串比较
    cout << "\n5. 字符串比较:" << endl;
    
    const char* s1 = "apple";
    const char* s2 = "banana";
    const char* s3 = "apple";
    
    cout << "strcmp(\"apple\", \"banana\"): " << strcmp(s1, s2) << endl;
    cout << "strcmp(\"banana\", \"apple\"): " << strcmp(s2, s1) << endl;
    cout << "strcmp(\"apple\", \"apple\"): " << strcmp(s1, s3) << endl;
    
    // 不区分大小写比较
    cout << "strcasecmp(\"Hello\", \"hello\"): " 
         << strcasecmp("Hello", "hello") << endl;
    
    // 6. 字符串查找
    cout << "\n6. 字符串查找:" << endl;
    
    const char* haystack = "The quick brown fox jumps over the lazy dog";
    const char* needle = "fox";
    
    char* found = strstr(haystack, needle);
    if (found) {
        cout << "找到 '" << needle << "' 在位置: " << (found - haystack) << endl;
        cout << "上下文: ..." << found << "..." << endl;
    }
    
    // 查找字符
    char* charFound = strchr(haystack, 'q');
    if (charFound) {
        cout << "找到字符 'q' 在位置: " << (charFound - haystack) << endl;
    }
    
    // 从后往前查找
    char* lastFound = strrchr(haystack, 'o');
    if (lastFound) {
        cout << "最后找到字符 'o' 在位置: " << (lastFound - haystack) << endl;
    }
    
    // 7. 字符串分割
    cout << "\n7. 字符串分割:" << endl;
    
    char data[] = "apple,banana,cherry,date,elderberry";
    cout << "原始字符串: " << data << endl;
    cout << "分割结果:" << endl;
    
    char* token = strtok(data, ",");
    int count = 1;
    while (token != nullptr) {
        cout << "  " << count++ << ". " << token << endl;
        token = strtok(nullptr, ",");
    }
    
    // 注意:strtok会修改原始字符串!
    
    // 8. 字符串转换
    cout << "\n8. 字符串转换:" << endl;
    
    // 字符串转数值
    const char* numStr = "123.45";
    int intVal = atoi("123");
    long longVal = atol("123456789");
    double doubleVal = atof(numStr);
    
    cout << "atoi(\"123\"): " << intVal << endl;
    cout << "atol(\"123456789\"): " << longVal << endl;
    cout << "atof(\"123.45\"): " << doubleVal << endl;
    
    // 数值转字符串
    char buffer[50];
    int num = 255;
    
    sprintf(buffer, "数字: %d, 十六进制: 0x%X", num, num);
    cout << "sprintf: " << buffer << endl;
    
    // 安全版本
    char safeBuffer[50];
    snprintf(safeBuffer, sizeof(safeBuffer), 
             "格式化: %d %.2f %s", 100, 3.14159, "test");
    cout << "snprintf: " << safeBuffer << endl;
}

// 手动实现字符串函数
void demonstrateManualStringFunctions() {
    cout << "\n=== 手动实现字符串函数 ===" << endl;
    
    // 1. 字符串长度
    auto myStrlen = [](const char* str) -> int {
        int len = 0;
        while (str[len] != '\0') {
            len++;
        }
        return len;
    };
    
    cout << "myStrlen(\"Hello\"): " << myStrlen("Hello") << endl;
    
    // 2. 字符串复制
    auto myStrcpy = [](char* dest, const char* src) -> char* {
        char* start = dest;
        while ((*dest++ = *src++) != '\0');
        return start;
    };
    
    char dest[20];
    myStrcpy(dest, "Copied!");
    cout << "myStrcpy: " << dest << endl;
    
    // 3. 字符串比较
    auto myStrcmp = [](const char* s1, const char* s2) -> int {
        while (*s1 && (*s1 == *s2)) {
            s1++;
            s2++;
        }
        return *(unsigned char*)s1 - *(unsigned char*)s2;
    };
    
    cout << "myStrcmp(\"abc\", \"abd\"): " << myStrcmp("abc", "abd") << endl;
    
    // 4. 字符串连接
    auto myStrcat = [](char* dest, const char* src) -> char* {
        char* start = dest;
        
        // 找到dest的结尾
        while (*dest != '\0') {
            dest++;
        }
        
        // 复制src
        while ((*dest++ = *src++) != '\0');
        
        return start;
    };
    
    char catDest[30] = "Hello";
    myStrcat(catDest, " World!");
    cout << "myStrcat: " << catDest << endl;
    
    // 5. 查找子串
    auto myStrstr = [](const char* haystack, const char* needle) -> const char* {
        if (*needle == '\0') {
            return haystack;
        }
        
        for (; *haystack != '\0'; haystack++) {
            const char* h = haystack;
            const char* n = needle;
            
            while (*h && *n && (*h == *n)) {
                h++;
                n++;
            }
            
            if (*n == '\0') {
                return haystack;
            }
        }
        
        return nullptr;
    };
    
    const char* result = myStrstr("Hello World", "World");
    if (result) {
        cout << "myStrstr找到: " << result << endl;
    }
}

// 字符串处理应用
void demonstrateStringApplications() {
    cout << "\n=== 字符串处理应用 ===" << endl;
    
    // 1. 统计单词
    cout << "1. 统计单词数量:" << endl;
    
    char sentence[] = "C++ is a powerful programming language";
    int wordCount = 0;
    bool inWord = false;
    
    for (int i = 0; sentence[i] != '\0'; i++) {
        if (isspace(sentence[i])) {
            inWord = false;
        } else if (!inWord) {
            wordCount++;
            inWord = true;
        }
    }
    
    cout << "句子: " << sentence << endl;
    cout << "单词数: " << wordCount << endl;
    
    // 2. 字符串反转
    cout << "\n2. 字符串反转:" << endl;
    
    char text[] = "Hello World";
    cout << "原始: " << text << endl;
    
    int len = strlen(text);
    for (int i = 0; i < len / 2; i++) {
        swap(text[i], text[len - 1 - i]);
    }
    
    cout << "反转: " << text << endl;
    
    // 3. 回文检查
    cout << "\n3. 回文检查:" << endl;
    
    char palindrome[] = "A man a plan a canal Panama";
    char cleaned[100];
    int cleanIndex = 0;
    
    // 清理字符串(移除空格,转小写)
    for (int i = 0; palindrome[i] != '\0'; i++) {
        if (isalpha(palindrome[i])) {
            cleaned[cleanIndex++] = tolower(palindrome[i]);
        }
    }
    cleaned[cleanIndex] = '\0';
    
    // 检查回文
    bool isPalindrome = true;
    int cleanLen = strlen(cleaned);
    for (int i = 0; i < cleanLen / 2; i++) {
        if (cleaned[i] != cleaned[cleanLen - 1 - i]) {
            isPalindrome = false;
            break;
        }
    }
    
    cout << "字符串: " << palindrome << endl;
    cout << "清理后: " << cleaned << endl;
    cout << "是否回文: " << (isPalindrome ? "是" : "否") << endl;
    
    // 4. 简单加密解密
    cout << "\n4. 凯撒密码加密解密:" << endl;
    
    char message[] = "Hello World";
    int shift = 3;
    
    cout << "原始消息: " << message << endl;
    
    // 加密
    char encrypted[100];
    for (int i = 0; message[i] != '\0'; i++) {
        if (isalpha(message[i])) {
            char base = islower(message[i]) ? 'a' : 'A';
            encrypted[i] = base + (message[i] - base + shift) % 26;
        } else {
            encrypted[i] = message[i];
        }
    }
    encrypted[strlen(message)] = '\0';
    
    cout << "加密后: " << encrypted << endl;
    
    // 解密
    char decrypted[100];
    for (int i = 0; encrypted[i] != '\0'; i++) {
        if (isalpha(encrypted[i])) {
            char base = islower(encrypted[i]) ? 'a' : 'A';
            decrypted[i] = base + (encrypted[i] - base - shift + 26) % 26;
        } else {
            decrypted[i] = encrypted[i];
        }
    }
    decrypted[strlen(encrypted)] = '\0';
    
    cout << "解密后: " << decrypted << endl;
}

int main() {
    demonstrateCStringOperations();
    demonstrateManualStringFunctions();
    demonstrateStringApplications();
    
    return 0;
}

10.4 函数指针

10.4.1 函数指针基础
cpp 复制代码
#include <iostream>
#include <cmath>
#include <functional>  // C++11 std::function
using namespace std;

// 函数指针:指向函数的指针
void demonstrateFunctionPointers() {
    cout << "=== 函数指针基础 ===" << endl;
    
    // 1. 函数指针的声明
    cout << "1. 函数指针的声明:" << endl;
    
    // 函数原型
    int add(int a, int b);
    double multiply(double a, double b);
    void printMessage(const char* message);
    
    // 声明函数指针
    int (*funcPtr1)(int, int);          // 指向返回int,接受两个int的函数
    double (*funcPtr2)(double, double); // 指向返回double,接受两个double的函数
    void (*funcPtr3)(const char*);      // 指向返回void,接受const char*的函数
    
    // 2. 初始化函数指针
    cout << "\n2. 初始化函数指针:" << endl;
    
    // 定义实际函数
    auto addImpl = [](int a, int b) -> int { return a + b; };
    auto multiplyImpl = [](double a, double b) -> double { return a * b; };
    auto printImpl = [](const char* msg) { cout << "消息: " << msg << endl; };
    
    // 初始化函数指针
    funcPtr1 = addImpl;
    funcPtr2 = multiplyImpl;
    funcPtr3 = printImpl;
    
    // 3. 通过函数指针调用函数
    cout << "\n3. 通过函数指针调用函数:" << endl;
    
    int sum = funcPtr1(10, 20);
    cout << "add(10, 20) = " << sum << endl;
    
    double product = funcPtr2(3.14, 2.0);
    cout << "multiply(3.14, 2.0) = " << product << endl;
    
    funcPtr3("Hello from function pointer!");
    
    // 4. 函数指针作为参数
    cout << "\n4. 函数指针作为参数:" << endl;
    
    auto calculator = [](double a, double b, double (*operation)(double, double)) {
        return operation(a, b);
    };
    
    // 定义一些数学运算
    auto power = [](double a, double b) -> double { return pow(a, b); };
    auto maximum = [](double a, double b) -> double { return a > b ? a : b; };
    
    cout << "5^3 = " << calculator(5, 3, power) << endl;
    cout << "max(7.5, 3.2) = " << calculator(7.5, 3.2, maximum) << endl;
    
    // 5. 函数指针数组
    cout << "\n5. 函数指针数组:" << endl;
    
    // 定义一些运算函数
    auto addFunc = [](double a, double b) -> double { return a + b; };
    auto subtractFunc = [](double a, double b) -> double { return a - b; };
    auto multiplyFunc = [](double a, double b) -> double { return a * b; };
    auto divideFunc = [](double a, double b) -> double { 
        return b != 0 ? a / b : 0; 
    };
    
    // 创建函数指针数组
    double (*operations[])(double, double) = {
        addFunc, subtractFunc, multiplyFunc, divideFunc
    };
    
    const char* operationNames[] = {"加", "减", "乘", "除"};
    
    double x = 10.0, y = 4.0;
    for (int i = 0; i < 4; i++) {
        cout << x << " " << operationNames[i] << " " << y 
             << " = " << operations[i](x, y) << endl;
    }
    
    // 6. 返回函数指针的函数
    cout << "\n6. 返回函数指针的函数:" << endl;
    
    auto getOperation = [](char op) -> double (*)(double, double) {
        switch (op) {
            case '+': return addFunc;
            case '-': return subtractFunc;
            case '*': return multiplyFunc;
            case '/': return divideFunc;
            default: return nullptr;
        }
    };
    
    char ops[] = {'+', '-', '*', '/'};
    for (char op : ops) {
        double (*func)(double, double) = getOperation(op);
        if (func) {
            cout << "8 " << op << " 2 = " << func(8, 2) << endl;
        }
    }
}

// 函数指针与回调函数
void demonstrateCallbacks() {
    cout << "\n=== 回调函数 ===" << endl;
    
    // 1. 排序回调
    cout << "1. 排序回调示例:" << endl;
    
    // 比较函数类型
    typedef bool (*CompareFunc)(int, int);
    
    // 不同的比较函数
    auto ascending = [](int a, int b) -> bool { return a < b; };
    auto descending = [](int a, int b) -> bool { return a > b; };
    auto byLastDigit = [](int a, int b) -> bool { return a % 10 < b % 10; };
    
    // 通用排序函数(使用回调)
    auto bubbleSort = [](int arr[], int size, CompareFunc compare) {
        for (int i = 0; i < size - 1; i++) {
            for (int j = 0; j < size - i - 1; j++) {
                if (compare(arr[j + 1], arr[j])) {
                    swap(arr[j], arr[j + 1]);
                }
            }
        }
    };
    
    int numbers[] = {42, 17, 89, 33, 56, 21, 78, 5, 91, 12};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    
    cout << "原始数组: ";
    for (int i = 0; i < size; i++) cout << numbers[i] << " ";
    cout << endl;
    
    // 升序排序
    int ascCopy[10];
    copy(numbers, numbers + size, ascCopy);
    bubbleSort(ascCopy, size, ascending);
    cout << "升序排序: ";
    for (int i = 0; i < size; i++) cout << ascCopy[i] << " ";
    cout << endl;
    
    // 降序排序
    int descCopy[10];
    copy(numbers, numbers + size, descCopy);
    bubbleSort(descCopy, size, descending);
    cout << "降序排序: ";
    for (int i = 0; i < size; i++) cout << descCopy[i] << " ";
    cout << endl;
    
    // 按个位数排序
    int digitCopy[10];
    copy(numbers, numbers + size, digitCopy);
    bubbleSort(digitCopy, size, byLastDigit);
    cout << "按个位数排序: ";
    for (int i = 0; i < size; i++) cout << digitCopy[i] << " ";
    cout << endl;
    
    // 2. 事件处理回调
    cout << "\n2. 事件处理回调示例:" << endl;
    
    // 事件类型
    enum Event { CLICK, HOVER, KEY_PRESS, MOUSE_MOVE };
    
    // 事件处理函数类型
    typedef void (*EventHandler)(Event, void*);
    
    // 模拟事件系统
    class EventSystem {
    private:
        EventHandler handlers[4] = {nullptr};
        void* userData[4] = {nullptr};
        
    public:
        void registerHandler(Event event, EventHandler handler, void* data = nullptr) {
            handlers[event] = handler;
            userData[event] = data;
        }
        
        void triggerEvent(Event event) {
            if (handlers[event]) {
                handlers[event](event, userData[event]);
            }
        }
    };
    
    // 事件处理函数
    auto clickHandler = [](Event e, void* data) {
        cout << "点击事件处理";
        if (data) {
            cout << ",数据: " << *(int*)data;
        }
        cout << endl;
    };
    
    auto keyHandler = [](Event e, void* data) {
        cout << "按键事件处理";
        if (data) {
            char* key = (char*)data;
            cout << ",按键: " << *key;
        }
        cout << endl;
    };
    
    // 使用事件系统
    EventSystem system;
    int clickData = 42;
    char keyData = 'A';
    
    system.registerHandler(CLICK, clickHandler, &clickData);
    system.registerHandler(KEY_PRESS, keyHandler, &keyData);
    
    system.triggerEvent(CLICK);
    system.triggerEvent(KEY_PRESS);
    
    // 3. 定时器回调
    cout << "\n3. 定时器回调示例:" << endl;
    
    typedef void (*TimerCallback)(int, void*);
    
    // 模拟定时器
    class Timer {
    private:
        TimerCallback callback;
        void* userData;
        int interval;
        int count;
        
    public:
        Timer(TimerCallback cb, void* data = nullptr, int interv = 1) 
            : callback(cb), userData(data), interval(interv), count(0) {}
        
        void tick() {
            count++;
            if (count % interval == 0) {
                if (callback) {
                    callback(count, userData);
                }
            }
        }
    };
    
    auto printTick = [](int tick, void* data) {
        cout << "定时器触发,次数: " << tick;
        if (data) {
            cout << ",消息: " << (const char*)data;
        }
        cout << endl;
    };
    
    const char* message = "定时器工作正常";
    Timer timer(printTick, (void*)message, 3);
    
    cout << "模拟10次tick:" << endl;
    for (int i = 0; i < 10; i++) {
        timer.tick();
    }
}

// C++11的替代方案:std::function
void demonstrateStdFunction() {
    cout << "\n=== C++11 std::function ===" << endl;
    
    // 1. std::function的基本使用
    cout << "1. std::function的基本使用:" << endl;
    
    #include <functional>
    
    // 声明函数对象
    function<int(int, int)> func;
    
    // 可以绑定各种可调用对象
    func = [](int a, int b) { return a + b; };
    cout << "lambda: " << func(10, 20) << endl;
    
    // 普通函数
    int subtract(int a, int b) { return a - b; }
    func = subtract;
    cout << "普通函数: " << func(20, 10) << endl;
    
    // 函数对象(仿函数)
    struct Multiplier {
        int factor;
        Multiplier(int f) : factor(f) {}
        int operator()(int a, int b) const {
            return a * b * factor;
        }
    };
    
    func = Multiplier(2);
    cout << "函数对象: " << func(3, 4) << endl;
    
    // 2. 更灵活的参数传递
    cout << "\n2. 更灵活的回调系统:" << endl;
    
    class EventHandler {
    private:
        function<void(int, const string&)> callback;
        
    public:
        void setCallback(function<void(int, const string&)> cb) {
            callback = cb;
        }
        
        void trigger(int id, const string& message) {
            if (callback) {
                callback(id, message);
            }
        }
    };
    
    EventHandler handler;
    
    // 设置不同的回调
    handler.setCallback([](int id, const string& msg) {
        cout << "事件 " << id << ": " << msg << endl;
    });
    
    handler.trigger(1, "用户登录");
    handler.trigger(2, "文件保存");
    
    // 3. 函数组合
    cout << "\n3. 函数组合:" << endl;
    
    function<double(double)> f = [](double x) { return x * 2; };
    function<double(double)> g = [](double x) { return x + 3; };
    
    // 组合函数 g(f(x))
    auto compose = [](function<double(double)> f, function<double(double)> g) {
        return [f, g](double x) { return g(f(x)); };
    };
    
    auto h = compose(f, g);
    cout << "f(x) = 2x, g(x) = x + 3" << endl;
    cout << "g(f(5)) = " << h(5) << endl;
    
    // 4. 与函数指针的比较
    cout << "\n4. std::function vs 函数指针:" << endl;
    cout << "函数指针的优点:" << endl;
    cout << "  - 更简单,更轻量" << endl;
    cout << "  - 与C兼容" << endl;
    cout << "  - 编译时类型检查" << endl;
    
    cout << "\nstd::function的优点:" << endl;
    cout << "  - 可以存储任何可调用对象" << endl;
    cout << "  - 更安全,避免空指针" << endl;
    cout << "  - 支持函数组合" << endl;
    cout << "  - 更好的类型擦除" << endl;
}

int main() {
    demonstrateFunctionPointers();
    demonstrateCallbacks();
    demonstrateStdFunction();
    
    return 0;
}

10.5 动态内存管理

10.5.1 new和delete操作符
cpp 复制代码
#include <iostream>
#include <cstdlib>  // malloc, free
#include <new>      // bad_alloc, nothrow
using namespace std;

void demonstrateNewDelete() {
    cout << "=== new和delete操作符 ===" << endl;
    
    // 1. 基本动态内存分配
    cout << "1. 基本动态内存分配:" << endl;
    
    // 分配单个整数
    int* singleInt = new int;
    *singleInt = 42;
    cout << "单个整数: " << *singleInt << endl;
    delete singleInt;      // 释放单个对象
    singleInt = nullptr;   // 好习惯
    
    // 分配整数数组
    int* intArray = new int[5];
    for (int i = 0; i < 5; i++) {
        intArray[i] = i * 10;
    }
    
    cout << "整数数组: ";
    for (int i = 0; i < 5; i++) {
        cout << intArray[i] << " ";
    }
    cout << endl;
    
    delete[] intArray;     // 释放数组
    intArray = nullptr;
    
    // 2. 对象动态分配
    cout << "\n2. 对象动态分配:" << endl;
    
    class Point {
    public:
        int x, y;
        Point(int x = 0, int y = 0) : x(x), y(y) {
            cout << "Point构造函数 (" << x << ", " << y << ")" << endl;
        }
        ~Point() {
            cout << "Point析构函数 (" << x << ", " << y << ")" << endl;
        }
        void print() const {
            cout << "(" << x << ", " << y << ")" << endl;
        }
    };
    
    // 分配单个对象
    Point* p1 = new Point(10, 20);
    p1->print();
    delete p1;
    p1 = nullptr;
    
    // 分配对象数组
    Point* points = new Point[3];
    for (int i = 0; i < 3; i++) {
        points[i].x = i * 10;
        points[i].y = i * 20;
    }
    
    cout << "对象数组: ";
    for (int i = 0; i < 3; i++) {
        points[i].print();
    }
    
    delete[] points;  // 调用每个对象的析构函数
    points = nullptr;
    
    // 3. 分配失败处理
    cout << "\n3. 分配失败处理:" << endl;
    
    // 方法1:使用nothrow
    int* hugeArray = new(nothrow) int[1000000000000LL];  // 尝试分配巨大内存
    if (hugeArray == nullptr) {
        cout << "内存分配失败 (nothrow版本)" << endl;
    } else {
        delete[] hugeArray;
    }
    
    // 方法2:捕获bad_alloc异常
    try {
        int* anotherHuge = new int[1000000000000LL];
        delete[] anotherHuge;
    } catch (const bad_alloc& e) {
        cout << "内存分配失败 (异常版本): " << e.what() << endl;
    }
    
    // 4. 定位new(Placement new)
    cout << "\n4. 定位new (Placement new):" << endl;
    
    // 预分配内存缓冲区
    char buffer[sizeof(Point) * 3];
    
    // 在缓冲区中构造对象
    Point* p2 = new(buffer) Point(1, 2);
    Point* p3 = new(buffer + sizeof(Point)) Point(3, 4);
    Point* p4 = new(buffer + 2 * sizeof(Point)) Point(5, 6);
    
    p2->print();
    p3->print();
    p4->print();
    
    // 需要手动调用析构函数
    p2->~Point();
    p3->~Point();
    p4->~Point();
    
    // 注意:不需要delete,因为内存不是new分配的
    
    // 5. 多维动态数组
    cout << "\n5. 多维动态数组:" << endl;
    
    int rows = 3, cols = 4;
    
    // 分配二维数组
    int** matrix = new int*[rows];
    for (int i = 0; i < rows; i++) {
        matrix[i] = new int[cols];
    }
    
    // 初始化
    int counter = 1;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            matrix[i][j] = counter++;
        }
    }
    
    // 显示
    cout << "动态二维数组:" << endl;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            cout << matrix[i][j] << "\t";
        }
        cout << endl;
    }
    
    // 释放内存(逆序)
    for (int i = 0; i < rows; i++) {
        delete[] matrix[i];
    }
    delete[] matrix;
}

// 与malloc/free的对比
void demonstrateMallocFree() {
    cout << "\n=== 与malloc/free的对比 ===" << endl;
    
    // 1. malloc/free的基本使用
    cout << "1. malloc/free的基本使用:" << endl;
    
    // 分配单个整数
    int* p1 = (int*)malloc(sizeof(int));
    if (p1 != nullptr) {
        *p1 = 100;
        cout << "malloc分配: " << *p1 << endl;
        free(p1);
        p1 = nullptr;
    }
    
    // 分配整数数组
    int* arr = (int*)malloc(5 * sizeof(int));
    if (arr != nullptr) {
        for (int i = 0; i < 5; i++) {
            arr[i] = i * 5;
        }
        
        cout << "malloc数组: ";
        for (int i = 0; i < 5; i++) {
            cout << arr[i] << " ";
        }
        cout << endl;
        
        free(arr);
        arr = nullptr;
    }
    
    // 重新分配内存
    int* dynamic = (int*)malloc(3 * sizeof(int));
    if (dynamic != nullptr) {
        for (int i = 0; i < 3; i++) dynamic[i] = i + 1;
        
        cout << "原始数组: ";
        for (int i = 0; i < 3; i++) cout << dynamic[i] << " ";
        cout << endl;
        
        // 扩大数组
        dynamic = (int*)realloc(dynamic, 6 * sizeof(int));
        if (dynamic != nullptr) {
            for (int i = 3; i < 6; i++) dynamic[i] = i + 1;
            
            cout << "扩展后: ";
            for (int i = 0; i < 6; i++) cout << dynamic[i] << " ";
            cout << endl;
        }
        
        free(dynamic);
        dynamic = nullptr;
    }
    
    // 2. new/delete vs malloc/free的区别
    cout << "\n2. new/delete vs malloc/free的区别:" << endl;
    
    class ComplexObject {
    public:
        int* data;
        
        ComplexObject(int size) {
            data = new int[size];
            cout << "构造函数调用" << endl;
        }
        
        ~ComplexObject() {
            delete[] data;
            cout << "析构函数调用" << endl;
        }
    };
    
    // 使用new/delete(正确)
    cout << "使用new/delete:" << endl;
    ComplexObject* obj1 = new ComplexObject(10);
    delete obj1;
    
    // 使用malloc/free(错误:不会调用构造函数和析构函数)
    cout << "\n使用malloc/free:" << endl;
    ComplexObject* obj2 = (ComplexObject*)malloc(sizeof(ComplexObject));
    // 构造函数没有被调用!
    // obj2->data = new int[10];  // 需要手动初始化
    
    // 手动调用构造函数(C++11之前的方式)
    // new(obj2) ComplexObject(10);
    
    // 手动调用析构函数
    // obj2->~ComplexObject();
    free(obj2);
    
    // 3. 内存泄漏检测
    cout << "\n3. 内存泄漏检测(简化示例):" << endl;
    
    class MemoryTracker {
    private:
        static int allocationCount;
        static int deallocationCount;
        
    public:
        static void* trackAlloc(size_t size) {
            allocationCount++;
            void* ptr = malloc(size);
            cout << "分配 #" << allocationCount << ": " << size 
                 << " 字节, 地址: " << ptr << endl;
            return ptr;
        }
        
        static void trackFree(void* ptr) {
            if (ptr != nullptr) {
                deallocationCount++;
                cout << "释放 #" << deallocationCount 
                     << ": 地址: " << ptr << endl;
                free(ptr);
            }
        }
        
        static void report() {
            cout << "\n内存追踪报告:" << endl;
            cout << "总分配次数: " << allocationCount << endl;
            cout << "总释放次数: " << deallocationCount << endl;
            cout << "潜在泄漏: " << (allocationCount - deallocationCount) << endl;
        }
    };
    
    int MemoryTracker::allocationCount = 0;
    int MemoryTracker::deallocationCount = 0;
    
    // 使用追踪器
    int* tracked1 = (int*)MemoryTracker::trackAlloc(sizeof(int));
    int* tracked2 = (int*)MemoryTracker::trackAlloc(10 * sizeof(int));
    
    MemoryTracker::trackFree(tracked1);
    // 故意不释放tracked2来模拟内存泄漏
    
    MemoryTracker::report();
    
    cout << "\n=== 总结 ===" << endl;
    cout << "new/delete 的优点:" << endl;
    cout << "  - 自动调用构造函数/析构函数" << endl;
    cout << "  - 类型安全" << endl;
    cout << "  - 自动计算大小" << endl;
    cout << "  - 支持异常" << endl;
    
    cout << "\nmalloc/free 的适用场景:" << endl;
    cout << "  - 与C代码交互" << endl;
    cout << "  - 需要realloc功能" << endl;
    cout << "  - 极致的性能要求(某些情况)" << endl;
}

// 智能指针(C++11)
#include <memory>

void demonstrateSmartPointers() {
    cout << "\n=== 智能指针(C++11)===" << endl;
    
    // 1. unique_ptr(独占所有权)
    cout << "1. unique_ptr(独占所有权):" << endl;
    
    // 创建unique_ptr
    unique_ptr<int> u1(new int(42));
    cout << "u1: " << *u1 << endl;
    
    // 移动语义(转移所有权)
    unique_ptr<int> u2 = move(u1);
    if (!u1) {
        cout << "u1变为空(所有权转移)" << endl;
    }
    cout << "u2: " << *u2 << endl;
    
    // 数组版本
    unique_ptr<int[]> u3(new int[5]);
    for (int i = 0; i < 5; i++) {
        u3[i] = i * 10;
    }
    cout << "u3数组: ";
    for (int i = 0; i < 5; i++) {
        cout << u3[i] << " ";
    }
    cout << endl;
    
    // make_unique(C++14)
    #if __cplusplus >= 201402L
    auto u4 = make_unique<double>(3.14159);
    cout << "make_unique: " << *u4 << endl;
    
    auto u5 = make_unique<int[]>(3);
    for (int i = 0; i < 3; i++) u5[i] = i * 100;
    #endif
    
    // 2. shared_ptr(共享所有权)
    cout << "\n2. shared_ptr(共享所有权):" << endl;
    
    class Resource {
    public:
        string name;
        Resource(const string& n) : name(n) {
            cout << "创建资源: " << name << endl;
        }
        ~Resource() {
            cout << "销毁资源: " << name << endl;
        }
    };
    
    // 创建shared_ptr
    shared_ptr<Resource> s1 = make_shared<Resource>("资源A");
    
    // 共享所有权
    shared_ptr<Resource> s2 = s1;
    shared_ptr<Resource> s3 = s2;
    
    cout << "引用计数: " << s1.use_count() << endl;
    
    // 当所有shared_ptr都销毁时,资源才会被释放
    s1.reset();
    cout << "s1释放后引用计数: " << s2.use_count() << endl;
    
    s2.reset();
    cout << "s2释放后引用计数: " << s3.use_count() << endl;
    
    s3.reset();  // 资源在这里被销毁
    cout << "所有shared_ptr已释放" << endl;
    
    // 3. weak_ptr(弱引用)
    cout << "\n3. weak_ptr(弱引用):" << endl;
    
    shared_ptr<Resource> shared = make_shared<Resource>("共享资源");
    weak_ptr<Resource> weak = shared;
    
    cout << "原始引用计数: " << shared.use_count() << endl;
    cout << "weak_ptr不增加引用计数" << endl;
    
    // 使用weak_ptr前需要转换为shared_ptr
    if (auto temp = weak.lock()) {
        cout << "通过weak_ptr访问: " << temp->name << endl;
    }
    
    // 释放共享所有权
    shared.reset();
    
    // 检查weak_ptr是否还有效
    if (weak.expired()) {
        cout << "weak_ptr已过期" << endl;
    }
    
    // 4. 智能指针与动态数组
    cout << "\n4. 智能指针与动态数组:" << endl;
    
    // 对于数组,使用unique_ptr<T[]>或shared_ptr(带自定义删除器)
    unique_ptr<int[]> smartArray(new int[10]);
    for (int i = 0; i < 10; i++) {
        smartArray[i] = i * 10;
    }
    
    cout << "智能指针数组: ";
    for (int i = 0; i < 10; i++) {
        cout << smartArray[i] << " ";
    }
    cout << endl;
    
    // 5. 自定义删除器
    cout << "\n5. 自定义删除器:" << endl;
    
    // 文件指针的自定义删除器
    auto fileDeleter = [](FILE* f) {
        if (f) {
            fclose(f);
            cout << "文件已关闭" << endl;
        }
    };
    
    unique_ptr<FILE, decltype(fileDeleter)> filePtr(fopen("test.txt", "w"), fileDeleter);
    if (filePtr) {
        fprintf(filePtr.get(), "Hello, Smart Pointer!");
        cout << "文件写入完成" << endl;
    }
    
    cout << "\n=== 智能指针的优点 ===" << endl;
    cout << "1. 自动内存管理,防止内存泄漏" << endl;
    cout << "2. 异常安全" << endl;
    cout << "3. 明确的所有权语义" << endl;
    cout << "4. 避免悬垂指针" << endl;
    cout << "5. 简化代码" << endl;
}

int main() {
    demonstrateNewDelete();
    demonstrateMallocFree();
    demonstrateSmartPointers();
    
    return 0;
}
10.5.2 动态内存管理的最佳实践
cpp 复制代码
#include <iostream>
#include <memory>
#include <vector>
#include <stdexcept>
using namespace std;

class MemoryManager {
private:
    struct AllocationInfo {
        void* ptr;
        size_t size;
        const char* file;
        int line;
        const char* function;
        
        AllocationInfo(void* p, size_t s, const char* f, int l, const char* fn)
            : ptr(p), size(s), file(f), line(l), function(fn) {}
    };
    
    static vector<AllocationInfo> allocations;
    
public:
    // 追踪分配
    static void* trackAlloc(size_t size, const char* file, int line, const char* function) {
        void* ptr = malloc(size);
        if (ptr) {
            allocations.emplace_back(ptr, size, file, line, function);
        }
        return ptr;
    }
    
    // 追踪释放
    static void trackFree(void* ptr) {
        if (ptr) {
            // 从列表中移除
            for (auto it = allocations.begin(); it != allocations.end(); ++it) {
                if (it->ptr == ptr) {
                    allocations.erase(it);
                    free(ptr);
                    return;
                }
            }
            cout << "警告:尝试释放未追踪的指针!" << endl;
            free(ptr);
        }
    }
    
    // 报告内存泄漏
    static void reportLeaks() {
        if (allocations.empty()) {
            cout << "未检测到内存泄漏" << endl;
        } else {
            cout << "检测到 " << allocations.size() << " 处内存泄漏:" << endl;
            for (const auto& alloc : allocations) {
                cout << "  泄漏 " << alloc.size << " 字节在 "
                     << alloc.file << ":" << alloc.line 
                     << " (" << alloc.function << ")" << endl;
            }
        }
    }
    
    // 重置追踪器
    static void reset() {
        allocations.clear();
    }
};

vector<MemoryManager::AllocationInfo> MemoryManager::allocations;

// 重载new/delete操作符进行追踪
void* operator new(size_t size, const char* file, int line) {
    void* ptr = MemoryManager::trackAlloc(size, file, line, __func__);
    if (!ptr) throw bad_alloc();
    return ptr;
}

void* operator new[](size_t size, const char* file, int line) {
    return operator new(size, file, line);
}

void operator delete(void* ptr) noexcept {
    MemoryManager::trackFree(ptr);
}

void operator delete[](void* ptr) noexcept {
    MemoryManager::trackFree(ptr);
}

// 宏简化使用
#define new new(__FILE__, __LINE__)

void demonstrateMemoryBestPractices() {
    cout << "=== 动态内存管理的最佳实践 ===" << endl;
    
    // 1. RAII(资源获取即初始化)原则
    cout << "\n1. RAII(资源获取即初始化)原则:" << endl;
    
    class RAIIFile {
    private:
        FILE* file;
        
    public:
        RAIIFile(const char* filename, const char* mode) {
            file = fopen(filename, mode);
            if (!file) {
                throw runtime_error("无法打开文件");
            }
            cout << "文件已打开" << endl;
        }
        
        ~RAIIFile() {
            if (file) {
                fclose(file);
                cout << "文件已关闭" << endl;
            }
        }
        
        // 禁止拷贝
        RAIIFile(const RAIIFile&) = delete;
        RAIIFile& operator=(const RAIIFile&) = delete;
        
        // 允许移动
        RAIIFile(RAIIFile&& other) noexcept : file(other.file) {
            other.file = nullptr;
        }
        
        RAIIFile& operator=(RAIIFile&& other) noexcept {
            if (this != &other) {
                if (file) fclose(file);
                file = other.file;
                other.file = nullptr;
            }
            return *this;
        }
        
        void write(const string& content) {
            if (file) {
                fprintf(file, "%s", content.c_str());
            }
        }
    };
    
    try {
        RAIIFile file("test.txt", "w");
        file.write("RAII示例\n");
        // 不需要手动关闭文件,析构函数会自动处理
    } catch (const exception& e) {
        cout << "错误: " << e.what() << endl;
    }
    
    // 2. 内存池(简化版)
    cout << "\n2. 内存池(简化版):" << endl;
    
    class MemoryPool {
    private:
        struct Block {
            Block* next;
        };
        
        Block* freeList;
        vector<void*> allocatedBlocks;
        size_t blockSize;
        size_t poolSize;
        
    public:
        MemoryPool(size_t blockSize, size_t numBlocks) 
            : blockSize(max(blockSize, sizeof(Block))), poolSize(blockSize * numBlocks) {
            
            // 分配大块内存
            char* pool = static_cast<char*>(malloc(poolSize));
            if (!pool) throw bad_alloc();
            
            allocatedBlocks.push_back(pool);
            freeList = nullptr;
            
            // 将内存块添加到空闲链表
            for (int i = numBlocks - 1; i >= 0; i--) {
                Block* block = reinterpret_cast<Block*>(pool + i * blockSize);
                block->next = freeList;
                freeList = block;
            }
            
            cout << "内存池已创建: " << numBlocks 
                 << " 个块,每块 " << blockSize << " 字节" << endl;
        }
        
        ~MemoryPool() {
            for (void* block : allocatedBlocks) {
                free(block);
            }
            cout << "内存池已销毁" << endl;
        }
        
        void* allocate() {
            if (!freeList) {
                cout << "内存池耗尽" << endl;
                return nullptr;
            }
            
            Block* block = freeList;
            freeList = freeList->next;
            
            cout << "从内存池分配: " << block << endl;
            return block;
        }
        
        void deallocate(void* ptr) {
            if (ptr) {
                Block* block = static_cast<Block*>(ptr);
                block->next = freeList;
                freeList = block;
                cout << "返回到内存池: " << ptr << endl;
            }
        }
    };
    
    // 使用内存池
    MemoryPool pool(sizeof(int), 5);
    
    int* p1 = static_cast<int*>(pool.allocate());
    int* p2 = static_cast<int*>(pool.allocate());
    int* p3 = static_cast<int*>(pool.allocate());
    
    if (p1) *p1 = 100;
    if (p2) *p2 = 200;
    if (p3) *p3 = 300;
    
    pool.deallocate(p2);
    pool.deallocate(p1);
    
    int* p4 = static_cast<int*>(pool.allocate());
    if (p4) *p4 = 400;
    
    // 3. 避免常见错误
    cout << "\n3. 避免常见错误:" << endl;
    
    // 错误1:忘记检查分配失败
    auto safeNew = [](size_t size) -> void* {
        void* ptr = malloc(size);
        if (!ptr) {
            throw bad_alloc();
        }
        return ptr;
    };
    
    // 错误2:不匹配的new/delete
    class CorrectDeallocation {
    public:
        void demonstrate() {
            // 单个对象
            int* single = new int;
            delete single;  // 不是delete[]
            
            // 数组
            int* array = new int[10];
            delete[] array;  // 不是delete
            
            // 使用智能指针避免问题
            auto smartSingle = make_unique<int>(42);
            auto smartArray = make_unique<int[]>(10);
        }
    };
    
    // 错误3:双重释放
    auto noDoubleFree = []() {
        int* ptr = new int(42);
        delete ptr;
        ptr = nullptr;  // 立即设为nullptr
        
        // delete ptr;  // 安全:删除nullptr是空操作
    };
    
    // 4. 内存对齐
    cout << "\n4. 内存对齐:" << endl;
    
    struct AlignedData {
        alignas(16) double data1;  // 16字节对齐
        alignas(8) int data2;      // 8字节对齐
        char data3;
    };
    
    cout << "AlignedData大小: " << sizeof(AlignedData) << endl;
    cout << "对齐要求: " << alignof(AlignedData) << endl;
    
    // 对齐的动态内存分配
    void* alignedMemory = aligned_alloc(16, 1024);  // C++17
    if (alignedMemory) {
        cout << "对齐内存分配成功: " << alignedMemory << endl;
        free(alignedMemory);
    }
    
    // 5. 自定义内存分配器(简化版)
    cout << "\n5. 自定义内存分配器:" << endl;
    
    template<typename T>
    class SimpleAllocator {
    private:
        MemoryPool& pool;
        
    public:
        using value_type = T;
        
        SimpleAllocator(MemoryPool& p) : pool(p) {}
        
        template<typename U>
        SimpleAllocator(const SimpleAllocator<U>& other) : pool(other.pool) {}
        
        T* allocate(size_t n) {
            if (n != 1) {
                throw bad_alloc();  // 简化:只支持单个元素
            }
            return static_cast<T*>(pool.allocate());
        }
        
        void deallocate(T* p, size_t n) {
            pool.deallocate(p);
        }
        
        template<typename U>
        bool operator==(const SimpleAllocator<U>& other) const {
            return &pool == &other.pool;
        }
        
        template<typename U>
        bool operator!=(const SimpleAllocator<U>& other) const {
            return !(*this == other);
        }
    };
    
    // 使用自定义分配器的vector
    MemoryPool intPool(sizeof(int), 100);
    vector<int, SimpleAllocator<int>> customVector({1, 2, 3, 4, 5}, SimpleAllocator<int>(intPool));
    
    cout << "使用自定义分配器的vector: ";
    for (int num : customVector) {
        cout << num << " ";
    }
    cout << endl;
}

// 内存泄漏检测演示
void demonstrateMemoryLeakDetection() {
    cout << "\n=== 内存泄漏检测演示 ===" << endl;
    
    // 启用内存追踪
    MemoryManager::reset();
    
    // 模拟内存泄漏
    int* leaked1 = new int(100);
    int* leaked2 = new int[10];
    
    // 正常分配和释放
    int* normal = new int(200);
    delete normal;
    
    // 报告泄漏
    MemoryManager::reportLeaks();
    
    // 清理泄漏(在实际程序中应该修复泄漏)
    delete leaked1;
    delete[] leaked2;
    
    MemoryManager::reset();
}

// 性能考虑
void demonstratePerformanceConsiderations() {
    cout << "\n=== 性能考虑 ===" << endl;
    
    const int ITERATIONS = 1000000;
    
    // 1. 测量new/delete的性能开销
    auto start = chrono::high_resolution_clock::now();
    
    for (int i = 0; i < ITERATIONS; i++) {
        int* ptr = new int(i);
        delete ptr;
    }
    
    auto end = chrono::high_resolution_clock::now();
    auto duration1 = chrono::duration_cast<chrono::milliseconds>(end - start);
    cout << "new/delete循环 " << ITERATIONS << " 次: " << duration1.count() << "ms" << endl;
    
    // 2. 一次性分配的性能
    start = chrono::high_resolution_clock::now();
    
    int* bulkArray = new int[ITERATIONS];
    for (int i = 0; i < ITERATIONS; i++) {
        bulkArray[i] = i;
    }
    delete[] bulkArray;
    
    end = chrono::high_resolution_clock::now();
    auto duration2 = chrono::duration_cast<chrono::milliseconds>(end - start);
    cout << "一次性分配: " << duration2.count() << "ms" << endl;
    
    cout << "性能提升: " 
         << (duration1.count() - duration2.count()) * 100.0 / duration1.count() 
         << "%" << endl;
    
    // 3. 缓存局部性
    cout << "\n3. 缓存局部性测试:" << endl;
    
    const int SIZE = 10000;
    int** matrix1 = new int*[SIZE];  // 指针数组
    for (int i = 0; i < SIZE; i++) {
        matrix1[i] = new int[SIZE];
    }
    
    int* matrix2 = new int[SIZE * SIZE];  // 扁平数组
    
    // 测试指针数组的访问速度
    start = chrono::high_resolution_clock::now();
    long sum1 = 0;
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            sum1 += matrix1[i][j];
        }
    }
    end = chrono::high_resolution_clock::now();
    auto duration3 = chrono::duration_cast<chrono::milliseconds>(end - start);
    
    // 测试扁平数组的访问速度
    start = chrono::high_resolution_clock::now();
    long sum2 = 0;
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            sum2 += matrix2[i * SIZE + j];
        }
    }
    end = chrono::high_resolution_clock::now();
    auto duration4 = chrono::duration_cast<chrono::milliseconds>(end - start);
    
    cout << "指针数组访问: " << duration3.count() << "ms" << endl;
    cout << "扁平数组访问: " << duration4.count() << "ms" << endl;
    cout << "性能差异: " 
         << (duration3.count() - duration4.count()) * 100.0 / duration3.count() 
         << "%" << endl;
    
    // 清理
    for (int i = 0; i < SIZE; i++) {
        delete[] matrix1[i];
    }
    delete[] matrix1;
    delete[] matrix2;
}

int main() {
    demonstrateMemoryBestPractices();
    demonstrateMemoryLeakDetection();
    demonstratePerformanceConsiderations();
    
    return 0;
}

10.6 实践练习

练习1:智能指针实现

cpp 复制代码
/*
 * 作业:实现简化版智能指针
 * 功能:
 * 1. 实现UniquePtr(独占所有权)
 * 2. 实现SharedPtr(共享所有权,引用计数)
 * 3. 实现WeakPtr(弱引用)
 * 4. 支持自定义删除器
 * 5. 支持移动语义
 * 
 * 要求:
 * - 不使用标准库智能指针
 * - 实现完整的RAII原则
 * - 处理自我赋值
 * - 提供异常安全保证
 * - 实现swap函数
 */

#include <iostream>
#include <type_traits>
using namespace std;

int main() {
    // 在这里编写你的代码
    
    return 0;
}

练习2:内存池分配器

cpp 复制代码
/*
 * 作业:高性能内存池分配器
 * 功能:
 * 1. 预分配大块内存
 * 2. 维护空闲链表
 * 3. 支持不同大小的内存块
 * 4. 线程安全(可选)
 * 5. 内存对齐
 * 6. 检测内存泄漏
 * 
 * 要求:
 * - 比标准new/delete更快
 * - 减少内存碎片
 * - 支持重新分配
 * - 与标准容器兼容
 * - 提供性能测试
 */

#include <iostream>
#include <vector>
#include <chrono>
#include <mutex>
using namespace std;

int main() {
    // 在这里编写你的代码
    
    return 0;
}

练习3:字符串类实现

cpp 复制代码
/*
 * 作业:实现C++字符串类
 * 功能:
 * 1. 动态内存管理
 * 2. 拷贝构造函数和赋值运算符
 * 3. 移动构造函数和移动赋值
 * 4. 常用字符串操作(连接、查找、替换)
 * 5. 迭代器支持
 * 6. 与C风格字符串互操作
 * 
 * 要求:
 * - 实现完整的RAII
 * - 避免不必要的拷贝
 * - 支持写时复制(可选)
 * - 异常安全
 * - 性能优化
 */

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

int main() {
    // 在这里编写你的代码
    
    return 0;
}

恭喜! 你已经完成了第六部分的学习。在这一部分中,你掌握了:

  1. 指针基础:内存地址、指针概念、指针运算
  2. 指针与数组:数组退化、多维数组指针
  3. 指针与字符串:C风格字符串操作
  4. 函数指针:回调函数、事件处理
  5. 动态内存管理:new/delete、malloc/free
  6. 智能指针:unique_ptr、shared_ptr、weak_ptr
  7. 最佳实践:RAII、内存池、性能优化

指针和动态内存是C++中最强大但也最容易出错的部分。现在你已经具备了安全、高效管理内存的能力。在接下来的第七部分中,我们将学习引用类型,这是C++中另一个重要的概念。

相关推荐
永远不打烊16 小时前
c++ 11 之 并发与多线程
c++
IT=>小脑虎16 小时前
2026版 Go语言零基础衔接进阶知识点【详解版】
开发语言·后端·golang
ChangYan.16 小时前
ffi-napi运行失败,报错:No native build was found,解决办法
开发语言
专注VB编程开发20年16 小时前
压栈顺序是反向(从右往左)的,但正因为是反向压栈,所以第一个参数反而离栈顶(ESP)最近。
java·开发语言·算法
say_fall16 小时前
C++ 类与对象易错点:初始化列表顺序 / 静态成员访问 / 隐式类型转换
android·java·开发语言·c++
热爱专研AI的学妹16 小时前
2026世界杯观赛工具自制指南:实时比分推送机器人搭建思路
开发语言·人工智能·python·业界资讯
Dev7z16 小时前
基于MATLAB图像处理的苹果品质自动分级系统设计与实现
开发语言·图像处理·matlab
源代码•宸17 小时前
Golang基础语法(go语言指针、go语言方法、go语言接口、go语言断言)
开发语言·经验分享·后端·golang·接口·指针·方法
Bony-17 小时前
Golang 常用工具
开发语言·后端·golang