C语言内存分配及释放
- 释放内存后,要把指针置为NULL,防止内存泄漏
#include <stdio.h>
#include <stdlib.h>
int main(){
int n;
scanf("%d",&n);
int *p=(int *) malloc(n*sizeof (int));
for (int i = 0; i < n; ++i) {
p[i]=i;
}
for (int i = 0; i < n; ++i) {
printf("%d\n",p[i]);
}
free(p);
p=NULL;
}
如果不释放,heap中太满了,则*ptr中存放null
用free(指针名)释放内存
内存泄漏
C++内存分配及释放
C++智能指针
教程1: SMART POINTERS in C++
- unique ptr
- shared ptr
在离开原来的scope后,原来shared的指针计数就自动减少了
教程2
#include "demo1.h"
#include <iostream>
#include <memory>
using namespace std;
class Foo{
int x;
public:
explicit Foo(int x):x(x){};
int getX(){
return x;
}
~Foo(){
cout<<"Foo Dest"<<endl;
}
};
int main(){
// 如果不加 delete f;,则存在内存泄漏,即不会调用析构函数
Foo *f=new Foo(10);
cout<<f->getX()<<endl; //
delete f;
cout<<"======"<<endl;
// 采用了智能指针,不存在内存泄漏
unique_ptr<Foo> p1(new Foo(10)); // 方式1
unique_ptr<Foo> p2=make_unique<Foo>(20); // 方式2
Foo *f1=new Foo(30); //方式3
unique_ptr<Foo> p3(f1);
cout<<p1->getX()<<endl; // 使用1
cout<<(*p2).getX()<<endl; //使用2
cout<<p3->getX()<<endl;
cout<<"======"<<endl;
Foo *f2=p2.get();
Foo *f3=p2.release();
cout<<f2->getX()<<endl; //
cout<<(*f3).getX()<<endl; //
cout<<"======"<<endl;
p2.reset(f3);
cout<<f2->getX()<<endl; //
return 0;
}
//10
//Foo Dest
//======
//10
//20
//30
//======
//20
//20
//======
//20
//Foo Dest
//Foo Dest
//Foo Dest
#include "demo1.h"
#include <iostream>
#include <memory>
using namespace std;
class Foo{
int x;
public:
explicit Foo(int x):x(x){};
int getX(){
return x;
}
~Foo(){
cout<<"Foo Dest"<<endl;
}
};
int main() {
shared_ptr<Foo>sp(new Foo(100));
cout<<sp->getX()<<endl;
cout<<sp.use_count()<<endl;
cout<<"======"<<endl;
shared_ptr<Foo>sp1=sp; // 如果用赋值,则计数增加
cout<<sp.use_count()<<endl;
cout<<sp1.use_count()<<endl;
cout<<"======"<<endl;
shared_ptr<Foo>&sp2=sp; // 如果传引用,则计数不会有影响
cout<<sp2.use_count()<<endl;
cout<<"======"<<endl; // 如果传指针,则计数不会有影响
shared_ptr<Foo>*sp3=&sp; // 如果传引用,则计数不会有影响
cout<<sp3->use_count()<<endl;
}
//100
//1
//======
//2
//2
//======
//2
//======
//2
//Foo Dest
多线程中使用
在数组中使用
unique_ptr 的数组智能指针,没有 和 -> 操作,但支持下标操作[]>
shared_ptr 的数组智能指针,有 和 -> 操作,但不支持下标操作[],只能通过 get() 去访问数组的元素>
shared_ptr 的数组智能指针,必须要自定义deleter
- unique_ptr
- shared_ptr
#include <iostream>
#include <cstdlib>
#include <vector>
#define N 2
using namespace std;
int main() {
// allocate N int memory blocks
int* ptr = (int*) malloc(N * sizeof(int));
for (int i = 0; i < N; i++) {
ptr[i] = i;
}
// 分配一片新的内存空间,并对其赋值
int* ptr1 = (int*) malloc(N * sizeof(int));
ptr1=ptr; //这里是浅拷贝
// print the values in allocated memories
for (int i = 0; i < N; i++) {
// ptr[i] and *(ptr+i) can be used interchangeably
cout << ptr1[i]<< endl;
cout <<*(ptr1+i)<< endl;
}
// 使用 shared_ptr 指针,然后用*(ptr2.get()+i) 取里面的元素
std::shared_ptr<int> ptr2(new int[N](), std::default_delete<int[]>());
ptr2= static_cast<const shared_ptr<int>>(ptr);
for (int i = 0; i < N; i++) {//
cout << ptr2.get()[i] << endl; // 或者 cout << *(ptr2.get()+i) << endl;
}
return 0;
}
另外,使用shared_ptr过程中有几点需要注意:构造shared_ptr的方法,如下示例代码所示,我们尽量使用shared_ptr构造函数或者make_shared的方式创建shared_ptr,禁止使用裸指针赋值的方式,这样会使shared_ptr难于管理指针的生命周期。
// 使用裸指针赋值构造,不推荐,裸指针被释放后,shared_ptr就野了,不能完全控制裸指针的生命周期,失去了智能指针价值
int *p = new int(10);
shared_ptr<int>sp = p;
delete p; // sp将成为野指针,使用sp将crash
// 将裸指针作为匿名指针传入构造函数,一般做法,让shared_ptr接管裸指针的生命周期,更安全
shared_ptr<int>sp1(new int(10));
// 使用make_shared,推荐做法,更符合工厂模式,可以连代码中的所有new,更高效;方法的参数是用来初始化模板类
shared_ptr<int>sp2 = make_shared<int>(10);