C++学习---动态内存

堆和栈

在C++中

  • 栈:是一种静态内存分配区域,用于存储局部变量和函数调用的上下文信息。在栈上的内存分配和释放都是自动管理的,遵循后进先出(LIFO)原则。
  • 堆:是一种动态内存分配区域,用于存储动态分配的数据,如对象、数据和数据结构等,在堆上的内存分配和释放需要显式管理,例如使用new或malloc操作符来分配内存,使用delete和free等操作符来释放内存。

在很多时候,你无法提前预知需要多少内存来存储某个定义变量中的特定信息,所需内存的大小需要在运行时才能确定。

在 C++ 中,您可以使用特殊的运算符为给定类型的变量在运行时分配堆内的内存,这会返回所分配的空间地址。这种运算符即 new 运算符。

如果您不再需要动态分配的内存空间,可以使用 delete 运算符,删除之前由 new 运算符分配的内存。


new和delete操作符

newdelete 运算符是C++中用于动态内存管理的操作符。它们允许你在堆上分配和释放内存,用于存储动态创建的对象和数据结构。

new 运算符:

  • new 运算符用于在堆上分配内存并构造一个对象。
  • 语法:new 数据类型new 数据类型[元素个数]
  • 对于单个对象的分配,new 返回指向该对象的指针。
  • 对于数组的分配,new 返回指向数组的首元素的指针。
  • 你需要手动释放使用 new 分配的内存,否则会导致内存泄漏。

例如,使用 new 创建一个整数对象的示例:

int* dynamicInt = new int; // 分配一个整数的内存
*dynamicInt = 42;

delete 运算符:

  • delete 运算符用于释放使用 new 分配的内存,并调用对象的析构函数(如果适用)。
  • 语法:delete 指针delete[] 指针
  • 你需要明确指定要释放的内存的指针,以避免悬挂指针问题。

例如,使用 delete 释放先前使用 new 分配的整数对象内存的示例:

delete dynamicInt; // 释放使用 new 分配的内存

newdelete 的数组形式:

你还可以使用 new[]delete[] 运算符来分配和释放动态数组的内存。在分配动态数组时,使用 new[],在释放内存时使用 delete[]。这些运算符对于分配和释放动态数组内存非常有用。

例如,使用 new[] 创建一个包含整数的数组,并使用 delete[] 释放内存的示例:

int* dynamicArray = new int[5]; // 分配一个包含 5 个整数的数组的内存
// 使用 dynamicArray 指向的内存
delete[] dynamicArray; // 释放使用 new[] 分配的数组内存

在C++中,可以通过检查指针是否为nullptr(空指针)来确定是否成功分配了内存。

例如:

int* dynamicInt = new int; // 尝试分配内存
if (dynamicInt != nullptr) {
    // 分配成功
    *dynamicInt = 42;
} else {
    // 分配失败
    // 执行错误处理逻辑
}

注:malloc() 函数在 C 语言中就出现了,在 C++ 中仍然存在,但建议尽量不要使用 malloc() 函数。new 与 malloc() 函数相比,其主要的优点是,new 不只是分配了内存,它还创建了对象。

完整的示例:

#include <iostream>

int main(){
    // 使用 new 分配内存并创建整数对象
    int* dynamicInt = new int;
    if (dynamicInt != nullptr){
        *dynamicInt = 42;
        std::cout << "Dynamic integer value: " << *dynamicInt << std::endl;
    } 
    else{
        std::cerr << "Memory allocation failed" << std::endl;
        return 1; // 退出程序,表示分配内存失败。
    }

    // 使用 delete 释放内存并销毁整数对象
    delete dynamicInt;

    return 0;
}

数组的动态内存分配

上面已经讲了关于new和delete的数组形式。扩展一下多维数组。

一维数组:

// 动态分配,数组长度为 m
int *array=new int [m];
 
//释放内存
delete [] array;

二维数组:

int **array;
// 假定数组第一维长度为 m, 第二维长度为 n
// 动态分配空间
array = new int *[m];
for( int i=0; i<m; i++ )
{
    array[i] = new int [n];
}
//释放
for( int i=0; i<m; i++ )
{
    delete [] array[i];
}
delete [] array;

示例:

#include <iostream>

int main() {
    int numRows = 3;
    int numCols = 4;

    // 动态分配二维数组
    int** dynamicArray = new int*[numRows]; // 分配行指针数组
    for (int i = 0; i < numRows; i++) {
        dynamicArray[i] = new int[numCols]; // 分配每行的列数组
    }

    // 初始化二维数组
    int count = 1;
    for (int i = 0; i < numRows; i++) {
        for (int j = 0; j < numCols; j++) {
            dynamicArray[i][j] = count++;
        }
    }

    // 打印二维数组
    for (int i = 0; i < numRows; i++) {
        for (int j = 0; j < numCols; j++) {
            std::cout << dynamicArray[i][j] << ' ';
        }
        std::cout << std::endl;
    }

    // 释放动态分配的内存
    for (int i = 0; i < numRows; i++) {
        delete[] dynamicArray[i]; // 释放每行的列数组
    }
    delete[] dynamicArray; // 释放行指针数组

    return 0;
}

三维数组:

int ***array;
// 假定数组第一维为 m, 第二维为 n, 第三维为h
// 动态分配空间
array = new int **[m];
for( int i=0; i<m; i++ )
{
    array[i] = new int *[n];
    for( int j=0; j<n; j++ )
    {
        array[i][j] = new int [h];
    }
}
//释放
for( int i=0; i<m; i++ )
{
    for( int j=0; j<n; j++ )
    {
        delete[] array[i][j];
    }
    delete[] array[i];
}
delete[] array;

示例:

#include <iostream>

int main() {
    int x = 3;
    int y = 4;
    int z = 2;

    // 动态分配三维数组
    int*** dynamicArray = new int**[x]; // 分配 x 个二维数组
    for (int i = 0; i < x; i++) {
        dynamicArray[i] = new int*[y]; // 分配每个二维数组的 y 行
        for (int j = 0; j < y; j++) {
            dynamicArray[i][j] = new int[z]; // 分配每行的 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++) {
                dynamicArray[i][j][k] = count++;
            }
        }
    }

    // 打印三维数组
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
            for (int k = 0; k < z; k++) {
                std::cout << dynamicArray[i][j][k] << ' ';
            }
            std::cout << std::endl;
        }
    }

    // 释放动态分配的内存
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
            delete[] dynamicArray[i][j]; // 释放每行的列数组
        }
        delete[] dynamicArray[i]; // 释放每个二维数组的行指针数组
    }
    delete[] dynamicArray; // 释放 x 个二维数组的指针数组

    return 0;
}

对象的动态内存分配

示例:

#include <iostream>
using namespace std;

class Box
{
    public:
        Box(){
            cout << "调用构造函数!" << endl;
        }
        ~Box(){
            cout << "调用析构函数!" << endl;
        }
};

int main()
{
    Box* myBoxArray = new Box[4];

    delete [] myBoxArray; // 删除数组

    return 0;
}

如果要为一个包含四个 Box 对象的数组分配内存,构造函数将被调用 4 次,同样地,当删除这些对象时,析构函数也将被调用相同的次数(4次)。

当上面的代码被编译和执行时,它会产生下列结果:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: C++ Boost库是一个广泛使用的开源库集合,为C++提供了许多功能强大的工具和算法。在Boost库中,有一个名为C++11 Boost库的子模块,它专门为支持C++11标准而设计。 C++11标准引入了许多新的语言特性和库组件,以提高编程效率和代码可靠性。而C++11 Boost库则扩展了标准库,为开发者提供了更多的功能和工具。 C++11 Boost库的中文手册是为了方便中国程序员使用该库而编写的文档。该手册详细介绍了C++11 Boost库中各个模块的功能、用法和示例代码。通过阅读中文手册,程序员可以更清晰地了解每个模块的用途,以及如何正确地使用它们。 在C++11 Boost库中,有许多常用的模块,比如smart_ptr模块,提供了智能指针的功能,用于管理动态内存;thread模块,用于创建和管理线程;filesystem模块,提供了对文件和目录的操作等。在中文手册中,为每个模块都提供了详细的说明和示例,帮助开发者快速上手和运用。 总之,C++11 Boost库中的中文手册为中国的程序员提供了方便和便捷的学习和使用Boost库的途径。通过阅读手册,开发者可以更加深入地了解每个模块的使用方法,从而更高效地开发和调试他们的C++程序。 ### 回答2: Boost库是一个C++的开源库集合,提供了丰富的功能和工具,可以帮助开发者更加高效地进行C++编程。Boost库中文手册是对Boost库的相关文档进行中文翻译的版本。 Boost库包含了众多的模块和组件,如智能指针、函数对象、线程、正则表达式、文件系统等,覆盖了C++开发中常用的领域。通过使用Boost库,开发者可以在项目中集成各种功能强大、稳定可靠的组件,提高代码的复用性和可维护性。 Boost库中文手册对于理解和学习Boost库的使用非常有帮助。手册中提供了详细的说明和示例代码,对于各个组件的功能、用法和特性进行了清晰的介绍,使得开发者可以快速上手和了解各个组件的使用细节。 通过学习Boost库中文手册,开发者可以深入了解各个模块和组件的详细功能和使用方法,使得他们能够更加灵活地利用Boost库来解决实际的开发问题。同时,手册中也提供了相应的参考资料和链接,方便开发者进一步扩展他们的学习和实践。 总之,Boost库中文手册是一个非常宝贵的资源,可以帮助开发者更好地利用Boost库进行C++编程。通过掌握Boost库提供的丰富功能和工具,开发者可以在项目中提高代码的效率和质量,同时也能够更好地满足对于C++编程的需求。 ### 回答3: Boost是一个开源的C++库,提供了很多功能丰富的组件,可以帮助开发者更轻松地进行C++程序开发。Boost库中包含了很多不同的模块,涵盖了各种不同的领域和功能。 11-boost库中文手册是指Boost库的第11章,该章节主要介绍了一些与字符串处理相关的功能组件。在这个章节中,我们可以了解到Boost库提供了一些强大的字符串处理工具,可以用于字符串的分割、合并、格式化、替换等操作。 例如,Boost库中的split函数可以帮助我们将一个字符串按照指定的分隔符进行分割,并将分割后的子字符串存入一个容器中。另外,Boost库还提供了format函数,用于格式化字符串,能够方便地将变量插入到字符串中。 此外,Boost库还提供了一些用于字符串匹配和替换的函数,例如regex_match和regex_replace等。这些函数可以帮助开发者高效地进行字符串模式匹配和替换。 总之,11-boost库中文手册是关于Boost库中字符串处理的部分。通过使用Boost库中提供的强大函数和组件,开发者可以更加方便地进行字符串处理和操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sciurdae.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值