我一直在尝试这个简单的代码和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;
}
问候
答案 0 :(得分:5)
C是assembly和机器代码的一步。它没有任何限制检查你。数组和字符串(也是数组)不知道它们有多长或分配了多少内存。他们只是指着记忆中的起点。
相反,走出记忆界限是undefined behavior这是C的说法&#34;这是一个错误,但我不必告诉你&#34 ;。检查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是一个很好的。