动态内存

代码包括:

  • 在自由存储区上分配内存
  • 指针只能位于栈上吗?否
  • 当内存分配失败,引发异常
  • 在栈上声明一个数组
  • 在自由存储区上声明一个数组
  • 在自由存储区上声明一个二维数组

代码如下:

#include <iostream>

int main() {
    {
        // 在 堆 上分配内存
        
        //int* ptr {nullptr};
        //ptr = new int;
        int* ptr {new int};

        delete ptr;
        ptr = nullptr;
    }

    {
        // 指针只能位于栈上吗?否

        int** handle {nullptr};
        handle = new int*;
        *handle = new int;

        // handle 是一个位于栈上的指针
        // *handle 是一个位于堆上的指针

        delete *handle;
        delete handle;
        handle = nullptr;
    }

    {
        // 当内存分配失败,引发异常
        // 使用 new(nothrow) 分配内存,不会引发异常,而是返回 nullptr

        int* ptr {new(std::nothrow) int};

        delete ptr;
        ptr = nullptr;
    }

    {
        // 在栈上声明一个数组
        // 数组中各个元素未初始化
        int myArray[5];
    }

    {
        // 在栈上声明一个数组,使用初始化列表为元素提供初始值
        //int myArray[5] {1,2,3,4,5};
        int myArray[] {1,2,3,4,5};
    }

    {
        // 在栈上声明一个数组,使用初始化列表为元素提供初始值
        // 若初始化列表包含的元素少于数组的大小,后面的元素将进行零初始化
        int myArray[5] {1,2};  // 1,2,0,0,0
    }

    {
        // 在栈上声明一个数组,将所有元素都初始化为零
        int myArray[5] {};  // 0,0,0,0,0
    }

    {
        // 在自由存储区上声明一个数组
        // 数组中各个元素未初始化
        int* myArrayPtr {new int[5]};

        delete[] myArrayPtr;
        myArrayPtr = nullptr;
    }

    {
        // 在自由存储区上声明一个数组
        // 使用 new(nothrow), 分配内存失败不会引发异常,而是返回 nullptr

        int* myArrayPtr {new(std::nothrow) int[5]};

        delete [] myArrayPtr;
        myArrayPtr = nullptr;
    }

    {
        // 在自由存储区上声明一个数组
        // 使用初始化列表为元素提供初始值
        int* myArrayPtr {new int[] {1,2,3,4,5}};

        delete [] myArrayPtr;
        myArrayPtr = nullptr;
    }

    {
        // 在自由存储区上声明一个数组
        // 数组的大小是动态的,在运行时确定
        class Document {};
        auto askUserForNumberOfDocuments {[](){return 5;}};
        std::size_t numberOfDocuments {askUserForNumberOfDocuments()};

        Document* documents {new Document[numberOfDocuments]{}};

        delete [] documents;
        documents = nullptr;
    }

    class Simple {
    public:
    Simple() {std::cout << "Simple constructor called!" << std::endl;}
    ~Simple() {std::cout << "Simple destructor called!" << std::endl;}
    };

    {
        // 在自由存储区上声明一个数组,数组由对象组成
        // new[] 会自动为每个对象调用零参(默认)构造函数
        // 对于基本类型的元素则不会,基本类型数组默认具有未初始化的元素

        Simple* mySimpleArray {new Simple[5]};
        // 等价于:
        //Simple* mySimpleArray {new Simple[5]{}};

        delete [] mySimpleArray;
        mySimpleArray = nullptr;
    }

    {
        // 在自由存储区上声明一个指针数组,数组元素指向各个对象

        // new
        const std::size_t arraySize{4};
        Simple** mySimplePtrArray {new Simple*[arraySize]};

        for (std::size_t i{0}; i < arraySize; ++i) {
            mySimplePtrArray[i] = new Simple;  // 等价于 new Simple{};
        }

        // delete
        for (std::size_t i{0}; i < arraySize; ++i) {
            delete mySimplePtrArray[i];
            mySimplePtrArray[i] = nullptr;
        }

        delete [] mySimplePtrArray;
        mySimplePtrArray = nullptr;
    }

    {
        // 在自由存储区上声明一个二维数组
        // 先为第一维度分配内存,然后为各个子数组分配内存
        const std::size_t xDimension {5};
        const std::size_t yDimension {4};

        // new
        char** myArray{new char*[xDimension]};
        for (std::size_t i{0}; i < xDimension; ++i) {
            myArray[i] = new char[yDimension];
        }

        // delete
        for (std::size_t i{0}; i < xDimension; ++i) {
            delete [] myArray[i];
            myArray[i] = nullptr;
        }
        delete [] myArray;
        myArray = nullptr;
    }

    {
        // 在自由存储区上声明一个二维数组,
        // 使用连续的内存块,大小为 xDimension * yDimension
        // 使用公式 x * xDimension + y 访问位置 (x, y) 的元素
        const std::size_t xDimension {5};
        const std::size_t yDimension {4};

        // new
        char* myArray {new char[xDimension * yDimension]};
        
        // 访问位置 (4, 3) 的元素(数组最后一个元素)
        const std::size_t pos {4 * xDimension + 3};
        myArray[pos] = 'A';

        // delete
        delete [] myArray;
        myArray = nullptr;
    }

    return 0;
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注