C++ 将变量声明为引用时释放后使用堆

C++ 将变量声明为引用时释放后使用堆,c++,heap,heap-memory,C++,Heap,Heap Memory,下面粘贴的代码返回释放后使用堆的错误。当我用coord&c=q.front()删除行上的参考符号“&”;q、 pop(),错误已解决 从我理解的,C++垃圾回收器删除了Q.Frror()中检索的COORD,当没有更多的引用时。虽然这里看起来coord&c中的c在从队列中弹出后立即从堆中删除,但尝试访问下一行中的c会导致错误 然而,这并不是每次都会发生,所以我想知道为什么会发生这种情况 class Solution { public: int numIslands(

下面粘贴的代码返回释放后使用堆的
错误。当我用
coord&c=q.front()删除行上的参考符号“&”;q、 pop(),错误已解决

从我理解的,C++垃圾回收器删除了Q.Frror()中检索的COORD,当没有更多的引用时。虽然这里看起来

coord&c
中的c在从队列中弹出后立即从堆中删除,但尝试访问下一行中的c会导致错误

然而,这并不是每次都会发生,所以我想知道为什么会发生这种情况

    class Solution {
    public:
        int numIslands(vector<vector<char>>& grid) {
            if(grid.size() == 0) return 0;
            typedef pair<int,int> coord;
            queue<coord> q;
            const int m = grid.size();
            const int n = grid[0].size();
            int i_in[] = {0,0,1,-1};
            int j_in[] = {1,-1,0,0};
            int ans = 0;
            for(int i = 0; i < m; ++i)
            {
                for(int j = 0; j < n; ++j)
                {
                    if(grid[i][j] == '1')
                    {
                        ++ans;
                        q.push(coord(i,j));
                        while(q.size() > 0)
                        {
                            coord &c = q.front(); q.pop();
                            grid[c.first][c.second] = '*';
                            for(int k = 0; k < 4; ++k)
                            {
                                int newi = c.first + i_in[k];
                                int newj = c.second + j_in[k];
                                if(newi >= 0 && newi < m &&
                                   newj >= 0 && newj < n && 
                                   grid[newi][newj] == '1')
                                {
                                    q.push(coord(newi, newj));
                                }
                            }
                        }
                    }
                }
            }
            return ans;
        }
    };
类解决方案{
公众:
国际努米斯兰(矢量和栅格){
if(grid.size()==0)返回0;
类型定义对坐标;
队列q;
const int m=grid.size();
常量int n=网格[0]。大小();
[]中的int i_={0,0,1,-1};
int j_in[]={1,-1,0,0};
int ans=0;
对于(int i=0;i0)
{
协调与控制=q.front();q.pop();
网格[c.first][c.second]='*';
对于(int k=0;k<4;++k)
{
int newi=c.first+i_in[k];
int newj=c.second+j_in[k];
如果(newi>=0&&newi=0&&newj
^^^此行将
c
设置为引用当前位于队列前面的

q.pop();
^^^此行删除队列前面的项目,并在过程中销毁它)。因此,在此行返回后,您的
c
引用指向一个无效对象,这意味着尝试使用
c
将调用未定义的行为

然而,这并不是每次都会发生,所以我想知道为什么会发生这种情况

    class Solution {
    public:
        int numIslands(vector<vector<char>>& grid) {
            if(grid.size() == 0) return 0;
            typedef pair<int,int> coord;
            queue<coord> q;
            const int m = grid.size();
            const int n = grid[0].size();
            int i_in[] = {0,0,1,-1};
            int j_in[] = {1,-1,0,0};
            int ans = 0;
            for(int i = 0; i < m; ++i)
            {
                for(int j = 0; j < n; ++j)
                {
                    if(grid[i][j] == '1')
                    {
                        ++ans;
                        q.push(coord(i,j));
                        while(q.size() > 0)
                        {
                            coord &c = q.front(); q.pop();
                            grid[c.first][c.second] = '*';
                            for(int k = 0; k < 4; ++k)
                            {
                                int newi = c.first + i_in[k];
                                int newj = c.second + j_in[k];
                                if(newi >= 0 && newi < m &&
                                   newj >= 0 && newj < n && 
                                   grid[newi][newj] == '1')
                                {
                                    q.push(coord(newi, newj));
                                }
                            }
                        }
                    }
                }
            }
            return ans;
        }
    };
发生的是,当您尝试使用悬空引用时会调用它。关于未定义的行为,有趣的是“一切似乎正常”是一个有效的结果,就像其他任何发生的事情一样——因为一旦调用了未定义的行为,所有的赌注都被取消了,编译器编写者没有任何义务使程序从此正确工作,世界也被打破了

要解决此问题,您可以删除符号(如您所做的那样),这样就没有引用,因此就不会出现悬空引用问题(因为您已将队列的
对象复制到局部变量中);或者,您也可以将对
q.pop()
的调用下移到while循环的末尾,这样,只有在执行了对
c
引用的所有使用之后,才会发生调用

^^^此行将
c
设置为引用当前位于队列前面的

q.pop();
^^^此行删除队列前面的项目,并在过程中销毁它)。因此,在此行返回后,您的
c
引用指向一个无效对象,这意味着尝试使用
c
将调用未定义的行为

然而,这并不是每次都会发生,所以我想知道为什么会发生这种情况

    class Solution {
    public:
        int numIslands(vector<vector<char>>& grid) {
            if(grid.size() == 0) return 0;
            typedef pair<int,int> coord;
            queue<coord> q;
            const int m = grid.size();
            const int n = grid[0].size();
            int i_in[] = {0,0,1,-1};
            int j_in[] = {1,-1,0,0};
            int ans = 0;
            for(int i = 0; i < m; ++i)
            {
                for(int j = 0; j < n; ++j)
                {
                    if(grid[i][j] == '1')
                    {
                        ++ans;
                        q.push(coord(i,j));
                        while(q.size() > 0)
                        {
                            coord &c = q.front(); q.pop();
                            grid[c.first][c.second] = '*';
                            for(int k = 0; k < 4; ++k)
                            {
                                int newi = c.first + i_in[k];
                                int newj = c.second + j_in[k];
                                if(newi >= 0 && newi < m &&
                                   newj >= 0 && newj < n && 
                                   grid[newi][newj] == '1')
                                {
                                    q.push(coord(newi, newj));
                                }
                            }
                        }
                    }
                }
            }
            return ans;
        }
    };
发生的是,当您尝试使用悬空引用时会调用它。关于未定义的行为,有趣的是“一切似乎正常”是一个有效的结果,就像其他任何发生的事情一样——因为一旦调用了未定义的行为,所有的赌注都被取消了,编译器编写者没有任何义务使程序从此正确工作,世界也被打破了


要解决此问题,您可以删除符号(如您所做的那样),这样就没有引用,因此就不会出现悬空引用问题(因为您已将队列的
对象复制到局部变量中);或者,您也可以将对
q.pop()
的调用下移到while循环的末尾,这样,只有在您对
c
引用的所有使用都已执行之后,才会发生调用。

coord&c=q.front();q、 pop()可能是原因。我觉得这很可疑。我的意思是POP移除了前面的项目,但是你有一个引用。<代码> C++垃圾回收器< /> >没有这样的东西,BTW.当我删除参考符号''与COORD和C=q.FrnTor()时,q、 pop();,错误已解决。这是正确的解决办法。标准的
c++
没有垃圾收集器。
coord&c=q.front();q、 pop()可能是原因。我觉得这很可疑。我的意思是POP移除了前面的项目,但是你有一个引用。<代码> C++垃圾回收器< /> >没有这样的东西,BTW.当我删除参考符号''与COORD和C=q.FrnTor()时,q、 pop();,错误已解决。这是正确的解决办法。标准
c++
没有垃圾收集器。