Size_t变量作为导致分段错误的循环计数器.为什么一旦i=0,循环就不退出



导致问题的代码如下所示:

for(size_t i = 10; i >= 0; i--){
cout << i  << ", ";
}

该输出:4,3,2,1,0,18446744073709551615,

然后程序返回一个分段错误,原因很明显,它试图访问荒谬索引中的项目。

为什么计数器不在0停止?

编辑:我在用网络编译器做作业。它没有提供任何警告。一般来说,我在本地开发,然后粘贴我所做的内容,因为我以前遇到过编译器问题。很高兴知道我并没有完全愚蠢,尽管问题很小。谢谢你的帮助!只是想我会在给出许多答案后添加一些额外的信息。

size_t是一个无符号积分。这意味着i永远不可能是负的。当i等于0,减去1,它将变成一个很大的数字,而不是-1

条件i >=0基本上说继续运行这个循环,直到i小于零。由于i的类型,这个条件永远不会满足。

编译器可能会向您指出这一点。我不确定你在用哪个编译器。但例如,如果使用gcc,则可以添加标志-Wsign-compare-Wtype-limits

编辑:更改为正确的gcc标志。积分转到@重复数据消除

当使用for循环从零到九进行计数时,需要执行以下操作:

for(int i = 0; i < 10; i++){
cout << i << endl;
}

注意,该循环的条件是i<10.在第九次迭代结束时,i被递增(i++(,然后被检查(i < 10(。

在您的情况下,i的类型是size_t,它是无符号的(也就是说,不能为负数(。由于下溢,一旦调用i--,i将从0变为size_t的最大值。由于该值为正,条件将返回true,for循环将继续。

如何解决此问题

请改用intSize_t通常用于表示容器的大小,这里不需要有:D。

如果比较总是非常正确(或错误(,许多编译器都会发出警告
在这种情况下,像size_t这样的无符号类型永远不能包含零以下的值。

当然,你必须表示有兴趣得到警告,注意是可选的。

为了便于演示,请参阅以下使用gcc和clang 在coliru上编译的程序

int main() {
for (unsigned i = 10; i >= 0; i--)
/**/;
}

如果你想处理整个范围,并使用单个无符号循环变量,重新排列一点就可以完成:

for (size_t i = 11; i-->0; )
/**/;

当然,i-->0可以简化为i--,但我无法链接">什么是"-->quot;C++中的运算符";。

在这种情况下,size_t是无符号的,很明显,当它为0时,它会在减少1后达到最大值。可能你在代码中的某个地方使用了这个计数器i来访问数组元素,然后它超出了边界,所以分段错误!

一个简单的解决方案看起来像:

for(size_t i = 10; i--;){
std::cout << i  << ", ";
}

通过这种方式,循环将挑衅地停止在零!

相关内容

  • 没有找到相关文章

最新更新