手把手教你学C++(二十八)--动态内存

目录

动态内存分配

使用 new

示例:分配单个对象

分配数组

示例:分配整型数组

动态内存释放

使用 delete

示例:释放单个对象

示例:释放数组

动态内存管理的最佳实践

1. 使用智能指针

示例:使用 std::unique_ptr

2. RAII(Resource Acquisition Is Initialization)

示例:使用 RAII 管理文件

3. 避免内存泄漏

示例:避免内存泄漏

4. 避免双删

示例:避免双删

动态内存分配的高级用法

1. 动态分配对象数组

2. 动态分配字符串

总结


 

动态内存管理是 C++ 编程中的一个重要方面,它允许程序在运行时分配和释放内存。动态内存通常用于那些大小或数量在程序运行时未知的数据结构,如动态数组、链表等。在 C++ 中,动态内存管理主要通过 newdelete 操作符来实现。

动态内存分配

使用 new

new 操作符用于在堆上分配内存,并返回指向所分配内存的指针。如果分配失败,new 会抛出一个 std::bad_alloc 异常。

示例:分配单个对象

 

cpp

深色版本

#include <iostream>
using namespace std;

int main() {
    int* ptr = new int; // 分配一个 int 对象的内存
    *ptr = 10;          // 给指针指向的内存赋值

    cout << "Value: " << *ptr << endl; // 输出 Value: 10

    delete ptr; // 释放内存
    return 0;
}

分配数组

new[] 操作符用于分配数组的内存。同样地,如果分配失败,new[] 也会抛出 std::bad_alloc 异常。

示例:分配整型数组

 

cpp

深色版本

#include <iostream>
using namespace std;

int main() {
    int size = 5;
    int* array = new int[size]; // 分配一个 int 数组的内存

    for (int i = 0; i < size; ++i) {
        array[i] = i * 2; // 给数组元素赋值
    }

    for (int i = 0; i < size; ++i) {
        cout << "array[" << i << "]: " << array[i] << endl; // 输出数组元素
    }

    delete[] array; // 释放数组内存
    return 0;
}

动态内存释放

使用 delete

delete 操作符用于释放先前通过 new 分配的内存。对于非数组对象,使用 delete;对于数组对象,使用 delete[]

示例:释放单个对象

 

cpp

深色版本

#include <iostream>
using namespace std;

int main() {
    int* ptr = new int;
    *ptr = 10;

    delete ptr; // 释放内存

    return 0;
}

示例:释放数组

 

cpp

深色版本

#include <iostream>
using namespace std;

int main() {
    int size = 5;
    int* array = new int[size];
    for (int i = 0; i < size; ++i) {
        array[i] = i * 2;
    }

    delete[] array; // 释放数组内存

    return 0;
}

动态内存管理的最佳实践

1. 使用智能指针

智能指针(如 std::unique_ptrstd::shared_ptrstd::weak_ptr)可以帮助自动管理动态分配的内存,避免内存泄漏和双删等问题。

示例:使用 std::unique_ptr

 

cpp

深色版本

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

int main() {
    unique_ptr<int> ptr(new int); // 使用智能指针
    *ptr = 10;

    // 智能指针会在离开作用域时自动释放内存
    return 0;
}

2. RAII(Resource Acquisition Is Initialization)

RAII 是一种编程技术,它通过在对象的生命周期内自动管理资源(如内存、文件句柄等),来确保资源的正确释放。

示例:使用 RAII 管理文件

 

cpp

深色版本

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

class SafeFile {
private:
    ofstream file;

public:
    SafeFile(const string& filename)
        : file(filename, ios::out | ios::binary) {
        if (!file.is_open()) {
            throw runtime_error("Failed to open file.");
        }
    }

    ~SafeFile() {
        file.close();
    }

    void write(const string& data) {
        if (!file) {
            throw runtime_error("Failed to write to file.");
        }
        file << data;
    }
};

int main() {
    try {
        SafeFile file("data.txt");
        file.write("Some data to be written.");
    }
    catch (const runtime_error& e) {
        cerr << "Caught exception: " << e.what() << endl;
    }

    return 0;
}

3. 避免内存泄漏

确保所有通过 new 分配的内存都通过 delete 释放,或者使用智能指针自动管理内存。

示例:避免内存泄漏

 

cpp

深色版本

#include <iostream>
using namespace std;

int main() {
    int* ptr = new int;
    *ptr = 10;

    delete ptr; // 不释放会导致内存泄漏

    return 0;
}

4. 避免双删

确保同一个指针只释放一次,避免重复释放内存。

示例:避免双删

 

cpp

深色版本

#include <iostream>
using namespace std;

int main() {
    int* ptr = new int;
    *ptr = 10;

    delete ptr; // 正确释放内存
    // delete ptr; // 错误:双删

    return 0;
}

动态内存分配的高级用法

1. 动态分配对象数组

 

cpp

深色版本

#include <iostream>
using namespace std;

class MyClass {
public:
    MyClass(int value) : m_value(value) {}
    void print() const { cout << "Value: " << m_value << endl; }

private:
    int m_value;
};

int main() {
    int size = 5;
    MyClass* objects = new MyClass[size];

    for (int i = 0; i < size; ++i) {
        objects[i] = MyClass(i * 2);
        objects[i].print();
    }

    delete[] objects; // 释放数组内存

    return 0;
}

2. 动态分配字符串

 

cpp

深色版本

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

int main() {
    const char* str = "Hello, World!";
    char* copy = new char[strlen(str) + 1];
    strcpy(copy, str);

    cout << "Copied String: " << copy << endl;

    delete[] copy; // 释放内存

    return 0;
}

总结

动态内存管理是 C++ 编程中不可或缺的一部分,它允许你在运行时根据需要分配和释放内存。通过使用 newdelete 操作符,可以灵活地管理动态内存。然而,手动管理内存容易引入内存泄漏、双删等问题。为了避免这些问题,现代 C++ 推荐使用智能指针(如 std::unique_ptrstd::shared_ptr)来自动管理内存。同时,采用 RAII 技术也可以帮助你更安全地管理资源。理解并正确应用这些技术和最佳实践,可以帮助你编写出更健壮、更高效的程序。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值