可执行程序(进程) 的虚拟地址空间:
内核: 操作系统
栈区:函数的形参,非静态的局部变量,函数现场保护数据等等,栈是向下增长的。
共享库的内存映射区域:用于装载一个共享的动态内存库。用户可使用系统接口创建共享内存,做进程间通信。
堆区: 用于程序运行时动态内存分配,堆是可以上增长的
数据段: 存储全局数据和静态数据,分为.bss 和.data
代码段: 可执行的程序(机器指令) 和 常量数据
C的动态内存管理:
int main()
{
int n = 10;
int* ip = (int*)malloc(sizeof(int) * n);
int* sp = (int*)calloc(n, sizeof(int)); //n*sizeof(int)
ipa = (int*)realloc(ipa, sizeof(int) * n * 2);
free(ipa);
ipa = NULL;
free(ipb);
ipb = NULL;
return 0;
}
int main()
{
int* ipa = (int*)malloc(sizeof(int)); //C
// bad_calloc //malloc realloc calloc nullptr
int* ips = new int(10); //c++
//1.sizeof(int); 2.malloc 3.initvalue
//new会对申请的空间拿()的值初始化 malloc只能够申请空间
//new 申请空间失败时 并不是返回一个空指针
//throw bad_calloc
free(ipa); ipa = nullptr; //malloc 把ipa指向的堆区空间还给系统
delete ips; ips = nullptr; //new
}
new:
int main()
{
int* p = new int(10); //
//1.计算类型大小
//int* p = (int*)malloc(sizeof(int))
//2.调用malloc 从堆区申请一个整型空间
//3.用括号里面的值初始化(10) malloc无法初始化
//4.申请的空间的地址给到p p只指向地址
//内存不足时 malloc返回一个空指针 new抛出异常
cout << *p << endl;
delete p;
//delete是把p所指向的堆内存还给系统
//free之后也要置为空
p = nullptr;
//置为空
}
int main()
{
int* ip = new int(10);
delete ip;
int* s = (int*)::operator new(sizeof(int));
// (int*)malloc(sizeof(int))
//如果堆区空间不足 不管是new 还是::operator new 会抛出异常 throw std::bad_alloc
//内存泄露:1 申请空间之后把地址丢了,2 程序运行时不断从堆区获取空间 耗损完堆空间
}
ip是一个空指针吗?
不是
malloc只管开辟内存(按字节开辟),不管初始化
new和delete,称作运算符
解析new delete
C++中解决动态内存分配的方案是把创建一个对象所需要的操作都结合在一个称为new的运算符里。当用new创建一个对象时,它就在堆里为对象分配内存并调用构造函数完成初始化。
new后边直接指定类型,如int,在堆上开辟int类型的内存。
小括号里面指定初始值。
所以这里的new不用进行类型转换了。
new不仅可以做内存开辟,还可以做内存初始化操作
malloc开辟内存失败,是通过返回值和nullptr空指针做比较;
new开辟数组内存时是不能在小括号进行初始化的。
这样写,是堆上只负责开辟数组,数组的元素不初始化。
这样写,是开辟的数组的所有元素都初始化为0
释放数组内存
int main()
{
int n = 10;
cin >> n;
int* ipa = (int*)malloc(sizeof(int) * n);
int* ips = new int[n]; //数组的概念: 申请一组空间1.sizeof(int)*10; 2.malloc, 3.初始化 4.把申请的空间ips
//怎么初始化
free(ipa);
ipa = nullptr;
delete[]ips;
ips = nullptr;
}
int main()
{
//1.按照关键字运算 new initvalue delete
//new的运算 1.按照关键字运算
int n = 10;
int* ipa = new int[n] {1, 2, 3, 4, 5, 6, 7};
delete[]ipa;
ipa = nullptr;
//连续空间初始化{}
}
//2.转变成函数 ::operator new(); not initvalue malloc
// ::operator delete();
int main()
{
int n = 10;
int* ipa = (int*)malloc(sizeof(int) * n);
if (nullptr == ipa)
{
return 1;
}
int* ips = (int*)::operator new(sizeof(int) * n,nothrow);
// throw bad_calloc
free(ipa); ipa = nullptr;
::operator delete(ips); ips = nullptr;
}
new 的函数方式的使用
定位new 对已经申请的空间初始化initvalue;
malloc 和new 的区别:
new不但能申请空间 还能对申请成功的空间初始化 malloc只能够申请空间;malloc申请空间失败返回空,new申请空间失败抛出异常(throw) ; ::operator new()申请空间失败抛出异常(throw) ,其他与malloc一样
区别:
1、 new/delete 是C++中的运算符。 malloc / free 是函数
2、 malloc申请内存空间时,手动计算所需大小,new只需类型名,自动计算大小,3、malloc申请的内存空间不会初始化,new可以初始化:
4、 malloc的返回值为void*,接收时必须强转,new不需要:5、malloc申请内存空间失败时,返回的是NULL,使用时必须判空new申请内存空间失败时抛出异常,所以要有捕获异常处理程序