我有一个 for 循环,它应该运行 4 次但运行了 6 次。 你能解释一下这种行为吗? 这很奇怪,因为 stringarr1 没有改变。
编辑:我想删除所有 '!'来 self 的第一个字符串并希望将字母保存在第二个字符串中。
#include <stdio.h>
#include <math.h>
#include <string.h>
int main(){
char stringarr1[] = "a!bc";
char stringarr2[] = "";
printf("%d\n", strlen(stringarr1)); // lenght --> 4
for (size_t i = 0; i < strlen(stringarr1); i++)
{
printf("i: %d\n", i);
if (stringarr1[i] != '!') {
stringarr2[strlen(stringarr2)] = stringarr1[i];
printf("info: != '!'\n");
}
}
}
最佳答案
您正在溢出 stringarr2
(长度为 1)的缓冲区,在这种情况下破坏了内存相邻的 stringarr1
,导致要通过覆盖其 nul 终止符来更改的字符串长度。
然后因为您要在每次迭代中重新评估字符串长度,所以循环将运行不确定的迭代次数 - 在您的情况下只有 6 次,但可能更糟;您观察到的行为只是几种可能性中的一种 - 未定义。
除了更正 stringarr2
的缓冲区长度外,最佳做法是对循环不变量求值一次(尽管在这种情况下,由于错误,字符串长度不是不变的)。所以如下:
const size_t length = strlen( stringarr1 ) ;
for( size_t i = 0; i < length; i++ )
{
...
将运行 4 次迭代,无论缓冲区溢出错误如何,因为在损坏后不会重新评估长度。重新评估循环不变量可能会导致代码执行非常缓慢。
关于c - for 循环运行太频繁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57783246/