new/delete与malloc/free区别
基本数据类型:int, char, short, long, double…及数组
int *p = new int(5);
cout<<" p="<<p<<endl;
delete p;
cout<<" p="<<p<<endl;
p = nullptr;
delete p;
int *p1((int *)malloc(4));
cout<<" p1="<<p1<<endl;
*p1=4;
cout<<" p1="<<p1<<endl;
free(p1);
cout<<" p1="<<p1<<endl;
自定义类型myData
class mydata{
public:
void *p;
mydata(){
p = malloc(1024*1024*100);
cout<<"mydata create"<<endl;
}
~mydata()
{
free(p);
cout<<"mydata delete"<<endl;
}
};
void test(){
mydata t1;
}
int main(){
mydata *p = new mydata;
delete p;
}
new/delete单个对象以及数组注意事项
*对自定义类型需要严格配对 new []/ delete []或者new/delete。
int *p = new int[3]{1,2,3};
cout<<p<<endl;
delete []p;
new分配内存,静态区\栈\堆
char str[1024] = { 0 };
int main(){
int *p = new int[3]{1,2,3};
int *p1 = new (str) int[3]{1,2,3};
cin.get();
return 1;
}
c++ new分配内存可以指定内存区域,一定程度上继承了unix系统的优良特性,Windows经常奔溃,Linux次之,Unix最为稳定,而Linux为android底层,Unix为iOS底层,这也是iOS较android更稳定的原因。这也是多数银行系统采用Unix做为服务系统的原因。 静态区\栈\堆的内存都可以覆盖重写,而唯独堆区内存可以delete重新利用。
new/delete重载
new/delete局部重载
单例的new/delete重载
int objs = 0;
void *g_p = nullptr;
using namespace std;
class mydata{
public:
mydata(){
cout<<"mydata create"<<endl;
}
~mydata()
{
cout<<"mydata delete"<<endl;
}
static void *operator new(size_t size){
if (g_p==nullptr) {
objs++;
mydata *p = ::new mydata();
cout<<"new call"<<endl;
g_p = p;
return p;
}else{
return g_p;
}
}
static void operator delete(void *p){
if (g_p != nullptr) {
objs--;
cout<<"delete call"<<endl;
::delete p;
}
}
};
int main(){
mydata *p1 = new mydata();
mydata *p2 = new mydata();
mydata *p3 = new mydata();
delete p1;
cout<<"objs="<<objs<<endl;
cin.get();
return 1;
}
new/delete全局重载
new=>::new=>malloc=>create;//分配内存优先于构造函数 decreate=>free=>::delete=>delete;//析构函数优先于释放内存
全局与局部new/delete分析
全局重载不完全,objs统计有问题
void * operator new (size_t size)
{
objs++;
cout<<"g_new call"<<endl;
void *p = malloc(size);
return p;
}
void operator delete(void *p) noexcept{
objs--;
cout<<"g_delete call"<<endl;
free(p);
}
void * operator new [] (size_t size)
{
objs++;
cout<<"g_new [] call"<<endl;
return operator new(size);
}
void operator delete [](void *p) noexcept{
objs--;
cout<<"g_delete [] call"<<endl;
free(p);
}
int main()
{
int *p = new int(5);
int *p2 = new int[10]{1,2,3,4,5,6,7,8,9,0};
cout<<"objs="<<objs<<endl;
delete p;
cout<<"objs="<<objs<<endl;
delete [] p2;
cout<<"objs="<<objs<<endl;
return 1;
}
局部重载,objs统计可以放在构造和析构函数
static int objs = 0;
void *g_p = nullptr;
using namespace std;
class mydata{
public:
void *p;
mydata(){
p = malloc(1024*1024*100);
cout<<"mydata create"<<endl;
objs++;
}
~mydata()
{
objs--;
free(p);
cout<<"mydata free"<<endl;
}
static void* operator new(size_t size);
static void operator delete(void* p)noexcept;
static void* operator new[](size_t size);
static void operator delete[](void* p);
};
void mydata::operator delete(void *pf)noexcept{
if (g_p != nullptr) {
cout<<"mydata delete call"<<endl;
free(pf);
}
}
void *mydata::operator new(size_t size){
if (g_p==nullptr) {
mydata *p = ::new mydata();
cout<<"mydata new call"<<endl;
g_p = p;
return p;
}else{
return g_p;
}
}
void *mydata::operator new [] (size_t size)
{
cout<<"mydata new [] call"<<" size="<<size<<endl;
void *p = malloc(size);
return p;
}
void mydata::operator delete [](void *p){
cout<<"mydata delete [] call"<<endl;
free(p);
}
int main()
{
mydata* pf = new mydata;
cout<<"objs="<<objs<<endl;
mydata* pf1 = new mydata[4];
cout<<"objs="<<objs<<endl;
delete pf;
cout<<"objs="<<objs<<endl;
delete[] pf1;
cout<<"objs="<<objs<<endl;
return 1;
}
也可以放在new/delete、new[]/delete[]里
static int objs = 0;
void *g_p = nullptr;
using namespace std;
class mydata{
public:
void *p;
mydata(){
p = malloc(1024*1024*100);
cout<<"mydata create"<<endl;
}
~mydata()
{
free(p);
cout<<"mydata free"<<endl;
}
static void* operator new(size_t size);
static void operator delete(void* p)noexcept;
static void* operator new[](size_t size);
static void operator delete[](void* p);
}
void mydata::operator delete(void *pf)noexcept{
if (g_p != nullptr) {
cout<<"mydata delete call"<<endl;
free(pf);
objs--;
}
}
void *mydata::operator new(size_t size){
if (g_p==nullptr) {
objs++;
mydata *p = ::new mydata();
cout<<"mydata new call"<<endl;
g_p = p;
return p;
}else{
return g_p;
}
}
void *mydata::operator new [] (size_t size)
{
short num = (short)size/sizeof(mydata);
objs+=num;
cout<<"mydata new [] call"<<" size="<<size<<endl;
void *p = malloc(size);
return p;
}
void mydata::operator delete [](void *p){
short num = (short)sizeof(&p)/sizeof(mydata);
objs-=num;
cout<<"mydata delete [] call"<<endl;
free(p);
}
list数据结构及双链表
list的应用
要了解c++的list实现细节可以参考C++链表的C实现(查找中间节点、判断是否存在环)
#include <list>
#include <list>
#include <iostream>
using namespace std;
int main()
{
list<int> mylist{1,2,3,4,5};
mylist.push_back(10);
for(auto i : mylist){
cout<<i<<endl;
}
cout<<endl;
mylist.assign(3,5);
for(auto i : mylist){
cout<<i<<endl;
}
cout<<endl;
mylist.assign(5,3);
mylist.push_front(9);
for(auto ib = mylist.begin(), ie = mylist.end();ib!=ie;ib++){
cout<<*ib<<endl;
}
cout<<endl;
for(auto rb = mylist.rbegin(), re = mylist.rend();rb!=re;rb++){
cout<<*rb<<endl;
}
cout<<"第一个L:"<<mylist.front()<<endl;
cout<<"最后一个:"<<mylist.back()<<endl;
cout<<"个数:"<<mylist.size()<<endl;
mylist.clear();
cout<<endl;
int a[10] {1,2,3,4,5,6,7,8,9,0};
mylist.assign(a, a+5);
for(auto ib = mylist.begin(), ie = mylist.end();ib!=ie;ib++){
cout<<*ib<<endl;
}
cout<<endl;
for(auto ib = mylist.begin(), ie = mylist.end();ib!=ie;ib++){
if (*ib==3) {
mylist.insert(ib, 123);
}
if (*ib==3) {
mylist.erase(ib);
break;
}
}
for(auto ib = mylist.begin(), ie = mylist.end();ib!=ie;ib++){
cout<<*ib<<endl;
}
cout<<endl;
mylist.pop_front();
mylist.pop_back();
mylist.reverse();
mylist.sort();
}
链表归并、交换,双链表及多链表
归并merge()
list<int> mylist1{1,2,3,4,5};
list<int> mylist2{6,7,8,9,0,10};
mylist1.merge(mylist2);
for(auto ib = mylist1.begin(), ie = mylist1.end();ib!=ie;ib++){
cout<<*ib<<endl;
}
交换swap()
list<int> mylist1{1,2,3,4,5};
list<int> mylist2{6,7,8,9,0,10};
mylist1.swap(mylist2);
for(auto ib = mylist1.begin(), ie = mylist1.end();ib!=ie;ib++){
cout<<*ib<<endl;
}
多链表
list<int> mylist1{11,12,33,4,5};
list<int> mylist2{6,17,8,12,9,0,10};
list<int> mylist3{6,17,8,12,9,0,10};
list<list<int>> mylist{mylist1,mylist2,mylist3};
for(auto i : mylist){
for(auto j :i){
cout<<j<<" ";
}
cout<<endl;
}
双链表管理一个类对象
类对象即使是空指针可以访问代码区函数,但是如果该函数访问局部变量,会因为没分配内存空间报错:
class MyClass{
public:
int i=0;
void show(){
messages_base();
}
my
};
int main(){
MyClass *myClass(nullptr);
myClass->show();
return 1;
}
对于类来说:类的函数共享,数据则是每个类对象私有的,空对象调用成员函数,没有访问数据,可以调用,访问数据不可以。
class MyClass;
struct Info{
MyClass *p;
int n;
};
list<Info> myClasslist;
class MyClass{
public:
void showMessage(){
cout<<"hello"<<endl;
}
MyClass(){
cout<<"MyClass()"<<endl;
}
~MyClass(){
cout<<"~MyClass()"<<endl;
}
void * operator new(size_t size){
void *p = malloc(size);
Info info;
info.p = (MyClass *)p;
if (size == sizeof(MyClass)) {
info.n = 1;
}else{
info.n = (int)(size-8)/sizeof(MyClass);
}
myClasslist.push_back(info);
return p;
}
void operator delete(void *p){
for (auto ib = myClasslist.begin(), ie = myClasslist.end(); ib != ie; ib++) {
if (p==(*ib).p) {
myClasslist.erase(ib);
free(p);
break;
}
}
}
void * operator new[](size_t size){
cout<<"new[]"<<size<<endl;
return operator new(size);
}
void operator delete[](void *p){
operator delete(p);
}
};
void showmemory(){
for(auto i : myClasslist){
cout<<"内存地址:"<<i.p<<" "<<"个数:"<<i.n<<endl;
}
}
void callAllObjs(){
for(auto myclass : myClasslist){
if (myclass.n == 1) {
myclass.p->showMessage();
}else{
for (int j=0; j<myclass.n; j++) {
myclass.p[j+1].showMessage();
}
}
}
}
int main(){
MyClass *p1 = new MyClass;
MyClass *p2 = new MyClass;
MyClass *pa1 = new MyClass[2];
delete p1;
delete p2;
MyClass *pa2 = new MyClass[3];
delete [] pa1;
showmemory();
callAllObjs();
return 1;
}
要是创建树结构
struct ClassInfo{
MyClass *p;
int n;
char name[10];
};
list<list<ClassInfo>> myTree;
|