扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
智能指针可以用来处理动态内存回收的问题
成都创新互联公司专注于企业网络营销推广、网站重做改版、宁陵网站定制设计、自适应品牌网站建设、成都h5网站建设、电子商务商城网站建设、集团公司官网建设、成都外贸网站建设公司、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为宁陵等各大城市提供网站开发制作服务。
但一旦令智能指针指向栈内存 如:
int a = 2; scoped_ptrspi1(&a);
程序肯定会发生崩溃。原因是在spi1出了作用域进行析构函数的时候,会对栈内存进行delete,这是不合法的。
假如能解决这个问题,我们的智能指针就能指向任何内存了。
(PS:智能指针被设计之初,就是用来解决动态内存的回收问题的。所以其实我这样折腾也许意义不大,纯属瞎搞)
我的思路是,重载operator new 和 operator delete操作符 ,
在operator new 中,将每次开辟的动态内存的地址存入一个数组arr(或者说顺序表),
在operator delete中,每次先判断要回收的内存是否在数组arr中:
若存在:说明要回收的内存是动态内存,执行回收,并将这个地址从数组arr中删掉
若不存在:说明要回收的内存是栈内存(静态内存),不执行回收,直接return掉。
由于目前采用的是全局重载的方式 operator new中的push_back操作也存在new ,如果用库里的vector或list ,一旦增添内容,将调用new,肯定会发生循环递归。
所以目前我采用的方式是自己写一个不支持动态增长的顺序表(很土的方法吧?)
目前只是个半成品,需要添、改的地方还很多,先厚着脸皮贴上来。
具体代码如下:
//万能new delete 模型(初步) #define DEFAULT_CAPA 100 using namespace std; struct DynamicMemoryAddr { void PushBack(void *data) { arr[_i++] = data; } void PopBack() { --_i; } int Find(void *data) { for (int i = 0; i < _i; i++) { if (arr[i] == data) { return i; } } return -1; } void Delede(void *data) { int i = Find(data); if (i == -1) { return; } else { for (int j = i; j < _i - 1; j++) { arr[j] = arr[j + 1]; } } --_sz; } void Print() { for (int i = 0; i < _i; i++) { cout << arr[i] << " "; } cout << endl; } void *arr[DEFAULT_CAPA]; int _i = 0; int _sz = DEFAULT_CAPA; }; DynamicMemoryAddr addr; void *operator new(size_t size) { cout << "operator new" << endl; void* ret = malloc(size); addr.PushBack(ret); return ret; } void operator delete(void *ptr) { if (addr.Find(ptr) == -1) //栈内存 { return; } else //堆内存 { cout << "delete : " << ptr << endl; addr.Delede(ptr); free(ptr); } } int main() { int *pi1 = new int(1); int *pi2 = new int(2); int *pi3 = new int(3); int a = 2; int *pi4 = &a; addr.Print(); delete pi1; delete pi2; delete pi3; return 0; }
目前的问题有:
1、我用的顺序表不支持动态增长,
2、全局重载并不是好的解决方案。
(待续)
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流