重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
智能指针可以用来处理动态内存回收的问题
从策划到设计制作,每一步都追求做到细腻,制作可持续发展的企业网站。为客户提供网站建设、成都做网站、网站策划、网页设计、主机域名、网络空间、网络营销、VI设计、 网站改版、漏洞修补等服务。为客户提供更好的一站式互联网解决方案,以客户的口碑塑造优易品牌,携手广大客户,共同发展进步。但一旦令智能指针指向栈内存 如:
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、全局重载并不是好的解决方案。
(待续)
创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。