简体   繁体   English

为什么我可以使用数组索引访问其他变量?

[英]Why am i able to access other variables using array indexing?

Here len is at A[10] and i is at A[11]. len在A [10],而i在A [11]。 Is there a way to catch these errors?? 有没有办法捕获这些错误? I tried compiling with gcc -Wall -W but no warnings are displayed. 我尝试使用gcc -Wall -W进行编译,但未显示警告。

int main()
{
  int A[10];
  int i, len;
  len = sizeof(A) / sizeof(0[A]);
  printf("Len = %d\n",len);
  for(i = 0; i < len; ++i){
    A[i] = i*19%7;
  }
  A[i] = 5;
  A[i + 1] = 6;
  printf("Len = %d i = %d\n",len,i);
  return 0;
}

Output : Len = 10 Len = 5 i = 6 输出: Len = 10 Len = 5 i = 6

You are accessing memory outside the bounds of the array; 您正在访问数组范围之外的内存; in C, there is no bounds checking done on array indices. 在C语言中,对数组索引没有边界检查。

Accessing memory beyond the end of the array technically results in undefined behavior . 从数组末尾访问内存在技术上导致未定义的行为 This means that there are no guarantees about what happens when you do it. 这意味着无法保证您在执行操作时会发生什么。 In your example, you end up overwriting the memory occupied by another variable. 在您的示例中,您最终将覆盖另一个变量占用的内存。 However, undefined behavior can also cause your application to crash, or worse. 但是,未定义的行为也可能导致您的应用程序崩溃甚至更糟。

Is there a way to catch these errors? 有没有办法捕获这些错误?

The compiler can catch some errors like this, but not many. 编译器可以捕获这样的一些错误,但是不会很多。 It is often impossible to catch this sort of error at compile-time and report a warning. 通常不可能在编译时捕获此类错误并报告警告。

Static analysis tools can catch other instances of this sort of error and are usually built to report warnings about code that is likely to cause this sort of error. 静态分析工具可以捕获此类错误的其他实例,并且通常用于报告有关可能导致此类错误的代码的警告。

C does not generally do bounds-checking, but a number of people have implemented bounds-checking for C. For instance there is a patch for GCC at http://sourceforge.net/projects/boundschecking/ . C通常不进行边界检查,但是许多人已经对C实现了边界检查。例如, http://sourceforge.net/projects/boundschecking/上有一个GCC补丁。 Of course bounds-checking does have some overhead, but it can often be enabled and disabled on a per-file basis. 当然,边界检查确实有一些开销,但是通常可以针对每个文件启用和禁用边界检查。

The array allocation of A is adjacent in memory to i and len. A的数组分配在内存中与i和len相邻。 Remember that when you address via an array, it's exactly like using pointers, and you're walking off the end of the array, bumping into the other stuff you put there. 请记住,当您通过数组寻址时,这就像使用指针一样,并且您正在走出数组的末端,碰到放置在其中的其他内容。

C by default does not do bounds checking. 默认情况下,C不进行边界检查。 You're expected to be careful as a programmer; 作为程序员,您应该格外小心。 in exchange you get speed and size benefits. 作为交换,您可以获得速度和尺寸上的好处。

Usually external tools, like lint, will catch the problems via static code analysis. 通常,外部工具(例如lint)将通过静态代码分析来解决问题。 Some libraries, depending on compiler vendor, will add additional padding or memory protection to detect when you've walked off the end. 某些库(取决于编译器供应商)将添加其他填充或内存保护,以检测何时结束运行。

Lots of interesting, dangerous, and non-portable things reside in memory at "random spots." 许多有趣,危险和不可携带的东西驻留在“随机位置”的内存中。 Most of the house keeping for heap memory allocations occur in memory locations before the one the compiler gives you. 堆内存分配的大多数内部维护发生在编译器提供给您的内存位置之前的内存位置。

The general rule is that if you didn't allocate or request it, don't mess with it. 一般规则是,如果您没有分配或请求它,请不要搞乱它。

i's location in memory is just past the end of A. That's not guaranteed with every compiler and every architecture, but most probably wouldn't have a reason to do it any other way. 我在内存中的位置刚好超过A的结尾。并不是每个编译器和每个体系结构都可以保证这一点,但是很可能没有其他理由这样做。

Note that counting from 0 to 9, you have 10 elements. 请注意,从0到9计数,您有10个元素。

Array indexing starts from 0. Hence the size of array is equal to one less than the declared value. 数组索引从0开始。因此,数组的大小等于声明值的1。 You are overwriting the memory beyond what is allowed. 您正在覆盖超出允许范围的内存。

These errors may not be reported as warnings but you can use tools like prevent, sparrow, Klockworks or purify to find such "malpractices" if i may call them that. 这些错误可能不会被报告为警告,但是如果我可以称呼它们,则可以使用诸如prevent,sparrow,Klockworks或purify之类的工具来查找此类“弊端”。

The short answer is that local variables are al-located on stack, and indexing is just like *(ptr + index). 简而言之,就是将局部变量分配在堆栈上,并且索引就像*(ptr + index)一样。 So it could happen that the room for int y[N] is adjacent to the room for another int x; 因此,可能发生的情况是int y [N]的空间与另一个int x的空间相邻; eg x is located after the last y. 例如x位于最后一个y之后。 So, y[N-1] is this last y, while y[N] is the int past the last y, and in this case, by accident, it happens you get x (or whatever in your practical example). 因此,y [N-1]是最后一个y,而y [N]是最后一个y之后的int,在这种情况下,偶然地,您会得到x(或实际示例中的任何值)。 But it is absolutely not a sure fact what you can get going past the bounds of an array and so you can't rely on that. 但这绝对不是一个事实,您可以超越数组的范围,因此您不能依赖它。 Even though undetected, it's a "index out of bound error", and a source of bugs. 即使未被检测到,它也是“错误索引超出范围”,并且是错误的来源。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我不能访问存储在另一个函数中的值? - Why am I not able to access values that were stored in another function? 我想创建一个数组,该数组的成员是其他数组的一部分。我无法找出错误 - I wanted to create an array whose members are part of other array .I am not being able to find out the error 无法弄清楚为什么我不从一个线程获取作为输入的数组并尝试使用另一个线程打印它 - Not able to figure out why am i not getting the array that i took as input from one thread and trying to print it using another 为什么我不能使用gcc生成“ Hello World”可执行文件? - Why am I not able to produce a “Hello World” executable using gcc? 为什么使用数组索引循环数组比指针访问慢? - Why looping over array using array indexing is slower than that of pointer access? 尝试访问C中的单个字节时,为什么我可以访问类型范围之外的字节? - When trying to access individual bytes in C, why am I able to access bytes outside of the range of the type? 为什么我无法初始化提供二维数组的指针数组 - why I am not able to initialize array of pointers providing 2d array 为什么我可以在这个例子中修改 char *? - Why am I able to modify char * in this example? 为什么我可以直接使用某些 ruby C 扩展数组方法,而不能直接使用其他方法? - Why am I able to directly use some of the ruby C extension array methods, but not others? 为什么由于使用char指针数组而出现细分错误? - Why am I getting Segmentation fault for using array of char pointers?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM