释放队列元素包含的指针指向的区域问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 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也可以执行,但不鼓励这样做。

猜你喜欢

转载自blog.csdn.net/fx_odyssey/article/details/79238332