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++
没有垃圾收集器。