malloc、calloc、realloc、free、malloc_trim

malloc、calloc、realloc、free

  1. malloc原型:void* malloc(unsigned int size)
  2. calloc原型:void* calloc(size_t numElements, size_t sizeOfElement)
    两个函数返回值均为系统分配的地址,失败返回NULL
    malloc最大分配空间:
    64位的,操作系统保留一部分内存(大概2G),还有差不多6G可以申请。32位可分配大致2G不到的内存(32位最大可识别内存4G,除去系统保留就是不到2G)。
    另外,程序是32位或者是64位并不是由你的操作系统决定,而是编译器决定,准确的说是决定于编译器和编译选项,64位系统照样可以跑32位的程序。

malloc和calloc一个很重要的区别是:malloc分配后的空间里是随机值,而calloc会初始化为0

  1. realloc原型:void* realloc(void *ptr, size_t new_Size)
    realloc用于对动态内存进行扩容(及已申请的动态空间不够使用,需要进行空间扩容操作)。ptr为指向原来空间基址的指针, new_size为接下来需要扩充容量的大小。
    分以下三种情况:
    ①如果size较小,原来申请的动态内存后面还有空余内存,系统将直接在原内存空间后面扩容,并返回原动态空间基地址。
    ②如果size较大,原来申请的空间后面没有足够大的空间扩容,系统将重新申请一块(20+size)*sizeof(int)的内存,并把原来空间的内容拷贝过去,原来空间free。
    ③如果size非常大,系统内存申请失败,返回NULL,原来的内存不会释放。

  2. free的调用形式为free(void*ptr):释放ptr所指向的一块内存空间。 malloc和calloc申请的空间都要free,防止泄露。记得释放后把ptr指向NULL,避免野指针。

char* p;
p=(char*)malloc(20*sizeof(char)); //malloc的参数size是需要内存空间的长度:
char* p;
p=(char*)calloc(20,sizeof(char)); //calloc第一个参数是元素个数,第二个是地址单位元素长度:
#include<iostream>
#include<cstdlib>
using namespace std;
 
int main() {
	int *c_p, *m_p;
	m_p = (int*)malloc(10 * sizeof(int));
	c_p = (int*)calloc(10, sizeof(int));
	cout << "malloc: ";
	for (int i = 0; i < 10; i++)
		cout  << m_p[i] << " ";
	cout << endl << "calloc: ";
	for (int i = 0; i < 10; i++)
		cout  << c_p[i] << " ";
	cout << endl;
	getchar();
	return 0;
}
#include<iostream>
#include<cstdlib>
using namespace std;
 
int main() {
	int *p, *r_p;
	p = (int*)malloc(10 * sizeof(int));
	r_p = (int*)realloc(p, 100);
	cout << "p: " << p << endl << "r_p: " << r_p << endl;
 
	getchar();
	return 0;
}

new和delete

只要告诉new为哪种数据类型分配内存,new会找到一个正确的内存块并返回指针:
int *p = new int;
使用delete会释放指针指向的内存,但不会删除指针本身。
delete p;
new和delete要成对使用,防止内存泄露。
下面两种情况注意:

// delete只能用于new分配的内存,因此下面这么做是不可以的
int test=5;
int *p=&test;
delete p;
 
// 但这么做是可以的
int *p=new int;
int *ps=p;
delete ps;
 

// 使用new时,可以在运行阶段根据需求建立数组。被称为动态联编,数组也叫动态数组。
int *p = new int[10];
 
delete [] p;

malloc和new的区别:
①malloc/free是库函数,而new和delete是C++的操作符。
②一个很大的区别是,malloc只负责分配内存,而new在分配后会调用默认构造函数,delete会调用默认析构函数。或者new还可以调用自定义的构造函数。因此malloc比较适合内部数据类型,对非内部数据动态对象,不太好初始化和销毁。
③上面提到的能否在运行时动态建立数组。
不能连续delete或者free一个指针,但delete和free对空指针操作不会出错。

C++允许重载new/delete操作符,特别的,布局new的就不需要为对象分配内存,而是指定了一个地址作为内存起始区域,new在这段内存上为对象调用构造函数完成初始化工作,并返回此地址。而malloc不允许重载。

memset和memcpy

原型: void *memset(void *s, int ch, size_t n) 其中:
s:为指针或是数组
ch:是赋给buffer的值
n:长度,要用sizeof(type)*num
功能:将s所指向的某一块内存中的前n个字节的内容全部设置为ch指定的ASCII值, 第一个值为指定的内存地址,块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向s的指针,它是对较大的结构体或数组进行清零操作的一种最快方法。
头文件是:<memory.h>或<string.h>
注意:memset是一个一个字节初始化的,char的话本身为一个字节。但像int之类的,如果不是初始化为0,可能不是你想要的结果。

原型:void memcpy(voiddest, const void *src, size_t n);
功能:由src指向地址为起始地址的连续n个字节的数据复制到以destin指向地址为起始地址的空间内。返回一个指向dest的指针。
#include<string.h>
注意:
①source和destin所指内存区域不能重叠。
②与strcpy相比,memcpy并不是遇到’\0’就结束,而是一定会拷贝完n个字节。
③如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。

malloc_trim()

使用 malloc_trim()可把之前分配的内存还给系统。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

陆不凡

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

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

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

打赏作者

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

抵扣说明:

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

余额充值