C是一个升压从assembly和机器代码。它没有界限检查你。数组和字符串(也是数组)不知道它们有多久或分配了多少内存。他们只是指向记忆中的起点。
相反,走在记忆范围之外的是undefined behavior这是C说“这是一个错误,但我不必告诉你”的方式。检查array[40][40]
会给你任何垃圾在该内存位置。它被称为buffer overflow。 array[0][0]
也会给你垃圾,因为数组从未初始化,C不会为你做。
...但操作系统可能。这被称为memory protection。操作系统通常不允许程序访问未分配的内存,并且其保护功能越来越好。但是,内存分配不是很好。操作系统不知道你分配了一个20乘20的整数数组,它只是给你的程序一大堆内存来处理,可能比它所要求的大,并且让程序在合适的时候分割它。
有各种工具可以帮助您解决C的疲劳症状。最重要的是Valgrind,这将是一个内存检查器,它将执行边界检查和更多。 Here's a tutorial on it。我无法推荐它。它可能有点模糊,但它会告诉你为什么你的程序不能正常工作,并将问题追溯到源头。
许多C编译器在默认情况下也没有警告。大多数命令行编译器都会响应-Wall
,但这些并不都是警告(这不是C第一次对你说谎)。有些使用-Weverything
或--pendantic
。一些编译器将做为你检查静态初始化的东西,如int array[20][20]
。例如,运行clang -Wall
(clang是在OS X中的默认C编译器)...
test.c:11:14: warning: array index 40 is past the end of the array (which contains 20 elements)
[-Warray-bounds]
int cc = array[40][40];
^ ~~
test.c:9:5: note: array 'array' declared here
int array[row][cols];
^
虽然这是学习标准C有用,把事情做好它不是一个很好的办法。一旦你对标准C的问题有所了解,我会建议看一下第三方库来改进C. Gnome Lib是一个不错的选择。
C没有边界检查你。 – Schwern
谢谢大家,现在我明白了,我会手动验证以确保安全。 –
@Ben这个问题有很多模糊之处。我刚刚添加了一个我知道的具体。 –