C:确保从数组返回的元素是正确的

假设我们有这段C代码:

 int x[] = {1, 2, 3, 4, 5}; printf("%d", *(x + 1)); //prints 2 printf("%d", *(x + 500)); //prints 7209065 (...?) 

正如你从第二次调用中看到的那样,它仍然会返回一些东西……但它是垃圾。

所以我问,你如何处理C中的这种情况? 也就是说,你怎么知道返回的元素是否真的是数组中存在的元素还是只是垃圾?

添加另一个包含数组长度的变量,每当您想要访问数组时,请确保您在数组的范围内。

简单地说,你不能。 这只是C和C ++语言的一个特性/错误/设计。

正如每个人都注意到的那样,由于C的性质,你不能这样做。但是,有一些工具可用于检测代码,并进一步检查内存访问(在开发周期中使用)。 Purify就是这样一种工具,我发现它可以用来识别这些问题。

不在运行时检查数组边界。 它们只是简单的内存块,其中包含类型的指示。 这是一种语言function,它可以减少代码的总开销。 无论喜欢与否,它就是它的本质。

通常,这就是创建“更智能”数据类型的原因 – 比如C ++的STL数组,它可以抛出索引越界错误的exception。

C不检查数组边界。 通过比较数组长度( sizeof(x)/sizeof(x[0]) ),您有责任检查访问是否在边界内。

实际上,要么是0端接的数组,在数组的末尾有0并且限制自己按顺序遍历它,要么传递包含数组长度的变量和数组,并在所有数组访问之前检查。

C中的数组本质上不知道它有多长,所以你不能得到任何免费依赖它的行为。

这也是为什么在使用数组的大多数(更可靠)C库中,您会看到作为参数传递的数组的大小,例如,fread()fwrite()

详细阐述JaredPar和Ed的答案:

C数组是一块连续的内存。 当你说int x [] = {1,2,3,4,5}时; C为5个整数分配足够的内存。 你要的是第500个元素,所以你得到的是没有正确分配给X的内存。它是垃圾,每次运行它都可能会改变。

我同意罗布。 添加一个包含X中元素数量的变量,并在每个变量中执行for循环。

如果您希望在运行时更改长度的数组有更好的方法来执行此操作。

在很大程度上,将C视为具有“数组”类型是错误的。 你正在使用的语法是指针周围的糖。 x [y]实际上是* x + sizeof(某事物)* y的语法糖(其中“某事”比我想要进入的更复杂;在这种情况下,某些东西是int )。

请记住,C是一种中级语言……一种“便携式组装”,你不会带来无根据的期望。

如果你足够“幸运”,或者你的指数偏差足够大,那么你就不会得到“垃圾” – 你会得到一个分段错误 。 但这实际上是件好事,因为它可以帮助你意识到你做错了什么。 一些工具会告诉您发生这种情况的确切行。

有时这取决于程序的输入,这意味着仅在插入某些输入时才会发生段错误(例如,如果您的’500’值是作为用户的输入接收的话)。 (那些找起来和处理起来比较烦人)

最有问题的案例是你得到“垃圾”和“无法知道它”的案例。

在这些情况下,首先编写好的代码实际上没有替代品。 但正如其他人所说, 动态和静态分析工具可能会有很大帮助。