1、关于代码中的数据存放在哪里的问题
1)只要是全局变量和静态变量都存放在数据段
2)局部变量存放在栈上,但是局部变量存储的内容是存放在代码段的
3)如果有malloc等的这些动态空间开辟的,变量存放在栈上,但是开辟出来的内容 存放在堆上
2、malloc/calloc/realloc
malloc:只开辟空间,不初始化
calloc(10,sizeof(int)):开辟空间,并按字节初始化为0
realloc(pb,sizeof(int)):如果pb是由calloc开辟出来的,则此时pb不需要再释放,因为realloc只是在原来开好的空间上进行调整而已,所以不能释放
realloc(void* ,newsize):调整空间
newsize<pb指向的空间大小,修改底层,释放多余的空间
newsize>pb指向的空间大小:1、如果pb之后还有足够的空间,只修改底层 (往后挪一点)
2、如果pb之后没有足够的空间,就开辟一个新的空间,再把原来的内容拷过来,释放原有空间。
#include<stdlib.h>
using namespace std;
void test()
{
int *p1 = (int*)malloc(sizeof(int));
free(p1);
int *p2 = (int*)calloc(4, sizeof(int));
int *p3 = (int*)realloc(p2, sizeof(int)* 10);
free(p3);
}
int main()
{
test();
system("pause");
return 0;
}
3、c++内存管理方式
1)new/delete 和 new[]/delete[]
void test2()
{
int* ptr4 = new int;//动态申请一个int类型的空间
int* ptr5 = new int(10);//动态申请一个int 类型的空间,并初始化为10,构造函数的参数有几个,括号里就有几个参数
int* ptr6 = new int[3];//动态申请3个int类型的空间
delete ptr4;
delete ptr5;
delete[] ptr6;
}
申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[]
2)new和delete操作自定义类型
class Test
{
public:
Test()
:_data(0)
{
cout << "Test():" << this << endl;
}
private:
int _data;
};
void Test2()//c版
{
Test* p1 = (Test*)malloc(sizeof(Test));//申请单个Test类型空间
free(p1);
Test* p2 = (Test*)malloc(sizeof(Test)* 10);//申请10个Test类型空间
free(p2);
}
void Test22()//c++版
{
Test* p1 = new Test;//申请单个Test类型的空间
delete p1;
Test* p2 = new Test[10];//申请10个Test类型的空间
delete[]p2;
}
3)malloc和new的区别?
malloc不会调构造函数new会调构造函数
new A[10]:相当于调了10次构造函数
delete和free的区别?
free不会调析构函数,delete 会调析构函数
5、operator new与operator delete(不是运算符重载,是一个全局函数)
new和delete是用户进行动态内存申请和释放的操作符,operator new和operator delete是系统提供的全局函数,new在底层调用operator new、delete在底层调用
operator delete来释放空间(其本质还是malloc和free)
operator new:本质是malloc+异常
operator delete:封装了free,没有异常(还钱不会失败)
operator new:封装了malloc+异常(借钱有可能会失败)
调用顺序:
new 自定义类型:new–>operator new–>malloc(内部)–>构造
delete 自定义类型:delete–>析构–>operator delete–>free(内部)
6、总结
c语言和c++内存管理的区别:
1)内置类型
malloc:只开辟空间,不初始化,空间开辟失败,返回NULL;
free:释放空间,失败抛异常
new:operator new–>malloc+异常
delete:delete–>operator delete–>free
new[n]:调用n次operator new
delete[] :调用n次operator delete
2)自定义类型
malloc:同上
free:同上
new:operator new–>malloc+异常–>构造,空间开辟失败抛异常
delete:delete–>析构–>operator delete–>free
new[]:调用n次operator new,n次构造
delete[]:调用n次operator delete,n次构造
7、定位new表达式
1)使用场景
我们知道malloc是不会调用构造函数的,如果用malloc申请一块空间,调new的定位表达式就可以调用构造函数,在已开好的空间上显示调用构造函数进行初始化。
class Test
{
public:
Test(int a)
:_data(0)
{
cout << "Test():" << this << endl;
}
~Test()
{
cout << "~Test():" << this << endl;
}
private:
int _data;
};
void test()
{
Test* pt = (Test*)malloc(sizeof(Test));//pt现在指向的只不过是与Test对象相同大小的一块空间,还不能算是一个对象,因为构造函数没有执行
new(pt) Test(1);//这里构造函数有参数,所以需要传参
}
int main()
{
test();
system("pause");
return 0;
}
执行结果是调用了构造函数