版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fx_odyssey/article/details/79238332
先看程序:
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <queue>
using namespace std;
bool DESTRUCT = true;
struct IMG
{
char *img;
int size;
IMG(){}
~IMG(){
printf("%s", this->img);
if (DESTRUCT)
{
delete[] this->img;
this->size = 0;
}
Sleep(1000);
}
};
int test()
{
char *str1 = new char[16];
strcpy(str1, "HelloWorld!\n");
queue<IMG> qImg;
IMG _img1;
_img1.img = str1;
_img1.size = strlen(str1);
qImg.push(_img1);
qImg.pop();
char *str2 = new char[16];
strcpy(str2, "Hello!\n");
IMG _img2;
_img2.img = str2;
_img2.size = strlen(str2);
qImg.push(_img2);
qImg.pop();
DESTRUCT = false;
return 0;
}
int main()
{
test();
system("\npause");
return 0;
}
备注:这个问题是在某个项目里遇到的。工程一创建了队列并push元素,然后将指向该队列的指针传给工程二。工程二里使用完后pop该队列。这时,pop操作时不执行队列元素的析构函数。所以,需要将pop操作封装,再将封装后的函数交给工程二调用,此时,正常执行pop操作,即析构被执行。
在结构IMG里,有一个指针img指向一块内存区。一般情况下正常执行push和pop是可以的。当重复执行push和pop次数达到上万或上百万时,内存会溢出。因为队列pop后,被抛弃的头元素和它指向的内存成了“野区”,没有被指,也无法被用,直到程序结束被彻底释放。内存空间有限,所以数据量特别大时,需要不停的释放。于是在析构里加入delete。在程序执行结束,析构会被再次调用,所以加入一个开关控制,防止被二次delete。
在析构函数中打断点,可以看到断点处跑了四次。分别是两次pop各执行一次,test函数运行结束执行两次。
建议:类比指针,跨工程delete也可以执行,但不鼓励这样做。