c和c++是如何申请和释放的?有什么区别?

本文详细介绍了C和C++语言中动态内存分配的相关函数,包括malloc、calloc、realloc和free,以及C++中new和delete的使用方法。重点强调了手动释放动态申请的内存空间的重要性。

C和C++ 语言动态内存分配

一、C语言动态内存分配

    要实现动态内存的分配,除了利用含指针成员的结构体之外,还需利用C语言提供的几个标准库函数。(使用时应包含头文件“alloc.h”或“malloc.h”或“stdlib.h”)

    1.malloc函数

  函数原型为void *malloc(unsigned int size);在内存的动态存储区中分配一块长度为"size" 字节的连续区域。函数的返回值为该区域的首地址。 “类型说明符”表示把该区域用于何种数据类型。(类型说明符*)表示把返回值强制转换为该类型指针。“size”是一个无符号数。例如: pc=(char *) malloc (100); 表示分配100个字节的内存空间,并强制转换为字符数组类型,函数的返回值为指向该字符数组的指针, 把该指针赋予指针变量pc。若size超出可用空间,则返回空指针值NULL。

    2.calloc 函数

    函数原型为void *calloc(unsigned int num, unsigned int size)

  按所给数据个数和每个数据所占字节数开辟存储空间。其中num为数据个数,size为每个数据所占字节数,故开辟的总字节数为num*size。函数返回该存储区的起始地址。calloc函数与malloc 函数的区别仅在于一次可以分配n块区域。例如: ps=(struct stu*) calloc(2,sizeof (struct stu)); 其中的sizeof(struct stu)是求stu的结构长度。因此该语句的意思是:按stu的长度分配2块连续区域,强制转换为stu类型,并把其首地址赋予指针变量ps。

    3. realloc函数:

  函数原型为void *realloc(void *ptr, unsigned int size)

      重新定义所开辟内存空间的大小。其中ptr所指的内存空间是用前述函数已开辟的,size为新的空间大小,其值可比原来大或小。函数返回新存储区的起始地址(该地址可能与以前的地址不同)。例如p1=(float *)realloc(p1,16);将原先开辟的8个字节调整为16个字节。

 **动态申请的内存空间要进行手动用free()函数释放

    4. free函数:

  函数原型为void free(void *ptr)

  将以前开辟的某内存空间释放。函数原型为 void free(void *ptr)其中ptr为存放待释放空间起始地址的指针变量,函数无返回值。应注意:ptr所指向的空间必须是前述函数所开辟的。例如free((void *)p1);将上例开辟的16个字节释放。可简写为free(p1);由系统自动进行类型转换。

二、C++语言动态内存分配

  C++语言中用new和delete来动态申请和释放内存。

    1. 申请单个对象

  int *p;

  p=new int;或者 p=new int(value);

  2. 动态申请数组

  int *p;

  p=new int [100];

  这样可以申请长度为100的数组,但是不能进行初始化。

 3. delete

  int *p, *q;

  p=new int;

  q=new int[10];

  delete p;

  delete [ ]q;

来源:http://www.cnblogs.com/zhj202190/archive/2011/05/11/2043620.html

<think> 在C/C++中,预留内存通常指的是在程序运行过程中,预先分配一块内存区域以供后续使用,这样可以避免频繁的内存分配操作,提高程序性能。常见的预留内存方式包括使用`std::vector`的`reserve()`方法,或者使用动态内存分配函数(如`malloc`、`calloc`、`realloc`或`new`)分配一块较大的内存,然后按需使用。 ### 预留内存的方法 1. **使用`std::vector::reserve`**: `std::vector`提供了`reserve(size_type n)`方法,用于预留至少能容纳`n`个元素的内存空间。注意,`reserve()`只改变`vector`的容量(capacity),而不改变其大小(size)。也就是说,它不会构造新的元素。 ```cpp #include <vector> std::vector<int> vec; vec.reserve(100); // 预留100个int的内存空间 ``` 2. **使用动态内存分配函数**: 使用`malloc`、`calloc`或`new`来分配一块内存,然后手动管理这块内存的使用释放。 ```cpp int* arr = (int*)malloc(100 * sizeof(int)); // C风格 // 或者 int* arr = new int[100]; // C++风格 ``` ### 如何释放预留的内存 1. **对于`std::vector`**: 当`vector`离开其作用域时,其析构函数会自动释放内存。也可以使用`clear()`方法清空所有元素(注意:`clear()`会销毁所有元素,但通常不会释放内存(即容量不变))。如果要释放预留的内存(即减少容量),可以使用`shrink_to_fit()`(C++11及以后)或者交换技巧(swap trick)。 - 使用`shrink_to_fit()`: ```cpp vec.clear(); vec.shrink_to_fit(); // 请求将容量减少至与大小匹配(即0),但不保证一定执行 ``` - 使用交换技巧: ```cpp std::vector<int>().swap(vec); // 用空向量交换,从而释放vec的内存 ``` 2. **对于动态分配的内存**: - 如果使用`malloc`/`calloc`分配,则使用`free`释放: ```cpp free(arr); ``` - 如果使用`new`分配,则使用`delete[]`释放(对于数组): ```cpp delete[] arr; ``` ### 注意事项 - 使用`reserve()`可以避免在向`vector`中添加元素时多次重新分配内存,从而提高性能。 - 动态分配的内存必须手动释放,否则会导致内存泄漏。 - 使用`realloc`可以调整之前分配的内存块的大小(仅用于C风格的`malloc`/`calloc`分配的内存)。 ### 示例:使用`vector`的`reserve`释放 ```cpp #include <vector> #include <iostream> int main() { std::vector<int> vec; vec.reserve(100); // 预留100个元素的内存 for (int i = 0; i < 100; ++i) { vec.push_back(i); // 不会导致重新分配 } // 清空并释放内存 vec.clear(); // 清空元素,但容量不变 vec.shrink_to_fit(); // 请求释放未使用的内存(容量变为0或很小) // 或者使用交换技巧 // std::vector<int>().swap(vec); std::cout << "Capacity after shrink_to_fit: " << vec.capacity() << std::endl; return 0; } ``` ### 总结 预留内存是一种优化技术,用于减少内存分配次数。在C++中,使用`std::vector::reserve`是推荐的方式,因为它自动管理内存,避免手动管理带来的错误。释放预留的内存时,对于`vector`可以使用`shrink_to_fit`或交换技巧;对于手动分配的内存,则必须使用对应的释放函数。 §§相关问题§§ 1. 在C++中,`std::vector`的`resize()``reserve()`有什么区别? 2. 使用`malloc``new`分配内存有什么不同,它们各自适用于什么场景? 3. 在C++中,如何避免内存泄漏?有哪些常见的内存管理技术? 4. `std::vector`的`shrink_to_fit()`方法是否一定能将容量减少到与大小相同?为什么? 5. 在C语言中,如何重新调整已分配内存的大小? </think>在C/C++中,预留内存(Preallocated Memory)是程序运行时预先申请但尚未立即使用的内存空间,通常用于优化性能(避免频繁分配/释放内存)或满足特定数据结构(如动态数组)的增长需求。 ### 主要方法及释放方式: #### 1. **C语言 `malloc/calloc/realloc`** ```c int* arr = (int*)malloc(100 * sizeof(int)); // 预留100个int的空间 ``` **释放方式**: ```c free(arr); // 释放整个内存块 ``` #### 2. **C++ `new` 运算符** ```cpp int* arr = new int[100]; // 预留100个int的连续空间 ``` **释放方式**: ```cpp delete[] arr; // 释放整个数组 ``` #### 3. **C++容器 `std::vector::reserve()`** ```cpp #include <vector> std::vector<int> vec; vec.reserve(100); // 预留100个元素的内存(不构造对象) ``` **释放方式**: - **显式释放**: ```cpp vec.clear(); // 清空元素 vec.shrink_to_fit(); // 释放多余内存C++11+) ``` - **交换技巧**(兼容旧标准): ```cpp std::vector<int>().swap(vec); // 用空容器交换内存 ``` #### 4. **C++11 智能指针 `std::unique_ptr`** ```cpp auto arr = std::make_unique<int[]>(100); // 预留100个int ``` **释放方式**:自动释放(超出作用域时)或手动重置: ```cpp arr.reset(); // 显式释放 ``` ### 关键注意事项: 1. **避免泄漏**:手动分配的内存(`malloc`/`new`)必须显式释放。 2. **容器优化**:`vector.reserve()` 仅分配内存,不构造对象;`resize()` 会构造对象。 3. **重新分配**:`realloc`(C)或 `vector` 自动扩容可能移动内存,使原指针失效。 4. **智能指针**:优先使用 `std::unique_ptr`/`std::vector` 减少手动管理风险。 ### 示例:`vector` 预留与释放 ```cpp #include <vector> #include <iostream> int main() { std::vector<int> vec; vec.reserve(100); // 预留100个int内存 std::cout << "Capacity: " << vec.capacity() << "\n"; // 输出100 vec.push_back(42); // 添加元素(不触发重新分配) vec.clear(); // 清空元素 vec.shrink_to_fit(); // 释放多余内存 std::cout << "Capacity: " << vec.capacity(); // 输出0 return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值