c - for 循环运行太频繁

标签 c arrays string for-loop

我有一个 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/

相关文章:

c - 我将如何使用 fgets 不读取空格

c++ - 如何知道消耗了多少堆栈函数?

C++:从字符串流到字符**

c - 如何检查动态分配

c - 如何在函数中分配数组,然后重新分配它

javascript - 确定 2 的幂?

c++ - 为什么将数组视为函数参数 C++ 中的指针?

c - 数组的空闲分配内存(与普通变量相比?)

c - 字符串终止 C/C++ char = 0

java - 删除数组中的重复项,Java