2016-06-01 59 views
-1

我一直在尝试这个简单的代码和C中的二维数组,不明白为什么我的程序不会失败。为什么我的代码不会出错?

假设指数超出范围?

#include <stdio.h> 
#include <stdlib.h> 
#define row 20 
#define cols 20 

int main(int argc, char *argv[]) 
{ 
    int x,y; 
    int array[row][cols];  

    int cc = array[40][40]; 

    return 0; 
} 

问候

+2

C没有边界检查你。 – Schwern

+0

谢谢大家,现在我明白了,我会手动验证以确保安全。 –

+0

@Ben这个问题有很多模糊之处。我刚刚添加了一个我知道的具体。 –

回答

5

C是一个升压从assembly和机器代码。它没有界限检查你。数组和字符串(也是数组)不知道它们有多久或分配了多少内存。他们只是指向记忆中的起点。

相反,走在记忆范围之外的是undefined behavior这是C说“这是一个错误,但我不必告诉你”的方式。检查array[40][40]会给你任何垃圾在该内存位置。它被称为buffer overflowarray[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 -Wallclang是在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是一个不错的选择。

+0

尝试修改出界内存更有可能失败。硬件更有可能捕获写入权限,如果不是,但会损坏关键指针或计数,则程序可能会在崩溃之间进行一些操作并显示为正常运行。一个不稳定的情况,导致突然崩溃“当它昨天工作很好”时。 – Gilbert

+0

@Gilbert:大多数硬件不会可靠地检测到任何此类访问或以特定方式运行。 C在非PC硬件上比在PC上使用更多。 – Olaf

+0

在大多数用C语言重量级库或甚至标准库编程的系统上都不可用。 – Olaf

相关问题