数据段的大小是根据VS2013开的全局数组测出来的,可能不是很准
内核:操作系统使用的空间,用户不能读写
栈:局部变量,局部数组等都在栈,栈向下生长,即栈往低地址生长
const修饰的变量得分情况,还得分c和c++
参考这个大佬的博客const修饰的变量的存储位置
内存映射段:与系统有关,待了解
数据段(静态区):存储全局数据和静态数据
代码段(常量区):可执行代码(二进制指令)和只读常量
const修饰的是变量,所以不叫只读常量
随笔记录:0x7fffffff相当于INT_MAX的一半,
//变量在内存里的分布demo
#include
#include
using namespace std;
//variable的意思是变量,var是variable的简称
int global_var;//数据段
static int static_global_var;//数据段(静态区)
int main()
{
static int static_var;//数据段
int local_var;//栈
char a[10]="abcd";//a在栈,数据也都在栈
*a;//*a在栈
char* b = "abcd";//b在栈,数据在代码区(常量区)
*b;//*b在代码区
int* ptr = (int*)malloc(10);//ptr在栈,开辟的空间在堆
*ptr;//堆
return 0;
}
通过malloc、calloc、realloc、free
//初始new delete
int main()
{
//C
int* ptr = (int*)malloc(sizeof(int));
free(ptr);
//C++
int* pa = new int;
delete pa;
return 0;
}
new是C++的一个关键字,用于动态内存分配
malloc是一个库函数
delete是C++的一个关键字,用于释放动态开辟的内存
类比free
//new、delete对于自定义类型调用构造、析构函数demo
class A
{
public:
A()
{
cout << "A()" << endl;
}
~A()
{
cout << "~A()" << endl;
}
};
int main()
{
A* pa1 = (A*)malloc(sizeof(A));
free(pa1);
cout << "malloc 和 free结束" << endl;
cout << endl;
A* pa2 = new A;
delete pa2;
cout << "new 和 delete结束" << endl;
return 0;
}
从这也可以看出new和malloc的区别之一就是会不会调用构造函数,delete和free的区别之一就是不会调用析构函数
//new、delete内置类型数组和自定义类型数组
class A
{
public:
A(){}
A(int){}
};
int main()
{
int* ptr = new int[10];//开一个十个int大小的数组
delete[] ptr;
int* ptr2 = new int(5);//开一个int大小的空间并且初始化为5
delete ptr2;
A* pa = new A[10];//开一个十个A类型大小的数组,调用十次构造函数
delete[] pa;
A* pa2 = new A(5);//会调用构造函数A(int)进行构造
delete pa2;
return 0;
}
汇编证明new的过程调用了构造函数
原则上new和delete成对使用,如果new和free配对使用,可能造成程序崩溃.
答: new和malloc在处理内置(基本)类型上没有差别,都只是动态开辟一块空间,但是C++还有面向对象的特性,虽然malooc给对象开辟了空间但是不会调用构造函数和析构函数,所以就出现了更能满足需求的new和delete
###malloc、free和new、delete的区别
#### operator new源码
这段源码在new.cpp中
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{ // try to allocate size bytes
void *p;
while ((p = malloc(size)) == 0)
if (_callnewh(size) == 0)
{ // report no memory
_THROW_NCEE(_XSTD bad_alloc, );
}
return (p);
}
由源码可以看出,如果返回的是空指针,则抛出异常
由源码可见operator new也不过是对malloc进行了封装
这块没找到源码,找到的资料大概意思是:operator delete这个函数相当于对free进行了封装
如果有大佬知道这个函数的源码位置,麻烦告诉我一下
随笔记录:operator delete释放空指针不报错
//类内重载operator new和operate delete的demo
#include
using namespace std;
class A
{
public:
void* operator new(size_t n)
{
cout << "void* operator new(size_t n)" << endl;
return nullptr;
}
void operator delete(void* p)
{
cout << "void operator delete(void* p)" << endl;
}
};
int main()
{
A* pa=new A;
delete pa;
return 0;
}
new:调用operaotr new函数开辟空间,再在空间上调用构造函数
delete:调用析构函数释放空间内的资源,再调用operator delete函数释放对象对象的空间
new T[N]:调用operator new开辟空间,再调用N次构造函数
delete[]:先执行N次析构函数,再把开辟的对象空间释放掉
我们说new与malloc的不同点之一是new会调用构造函数
回顾一下之前调用构造函数的情形:定义对象或者new一个对象时都会调用构造函数,且是自动调用的
如果我们要对malloc出来的空间手动调用构造函数应该怎么办?
此时就需要placement new,即定位new表达式
placement new也叫定位new表达式
作用:在已分配的空间调用构造函数初始化对象
比如我们malloc后调用构造函数初始化对象
使用场景:内存池等
用法:new(指向对象的指针)类名(构造函数参数)
//定位new表达式的用法demo
class A
{
public:
A()
{
cout << "A()"<~A();
free(pa);
return 0;
}