2016-06-01 4 views
-1

나는이 간단한 코드와 2 차원 배열을 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 overflow으로 알려져 있습니다. 배열이 초기화되지 않았기 때문에 array[0][0]도 쓰레기를 줄 것이며 C는 그렇게하지 않습니다.

...하지만 운영 체제에 따라 다를 수 있습니다. 이를 memory protection이라고합니다. 운영 체제는 일반적으로 프로그램이 할당되지 않은 메모리에 액세스하는 것을 허용하지 않으며 보호 기능이 향상되고 있습니다. 그러나 메모리 할당은 세분화되지 않습니다. 운영체제는 20 x 20 정수 배열을 할당했다는 사실을 알지 못한다. 단지 프로그램이 메모리를 요구할 것보다 더 큰 메모리를 제공하고 프로그램을 적절하게 슬라이스하게 남겨둔다.

C의 과장 행동에 도움이되는 다양한 도구가 있습니다. 가장 중요한 것은 Valgrind으로 경계 검사를하고 훨씬 더 많은 메모리 검사기입니다. Here's a tutorial on it. 나는 그것을 충분히 추천 할 수 없다. 약간은 어둡지 만 프로그램이 조용하게 작동하지 않는 이유를 알려주고 문제를 소스로 추적합니다.

많은 C 컴파일러에는 기본적으로 경고가 설정되어 있지 않습니다. 대부분의 명령 행 컴파일러는 -Wall에 응답하지만, 모든 경고가 아닙니다 (C가 처음으로 거짓말하는 것은 아닙니다). 일부는 -Weverything 또는 --pendantic을 사용합니다. 일부 컴파일러는 int array[20][20]과 같이 정적으로 초기화 된 것들에 대해 경계 검사를 수행합니다. 이 표준 C를 배울 유용 예를 들어, (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];  
    ^

clang -Wall을 실행이 아니 아주 좋은 방법 일 완료하세요. 표준 C의 문제에 대한 경험이 있으면 C를 향상시키기 위해 제 3 자 라이브러리를 살펴볼 것을 제안합니다. Gnome Lib은 좋은 것입니다.

+0

바운드 메모리를 수정하려고 시도하면 오류가 발생할 가능성이 큽니다. 하드웨어는 쓰기 액세스를 잡을 확률이 더 높습니다. 그렇지만 크리티컬 포인터 또는 카운트를 손상시키는 경우 프로그램은 충돌 사이에서 무언가를 수행하고 정상적으로 실행되는 것처럼 보일 수 있습니다. 어제는 잘 작동했을 때 갑작스런 충돌을 초래하는 불안정한 상태. – Gilbert

+0

@ Gilbert : 대부분의 하드웨어는 이러한 액세스를 안정적으로 감지하지 못하거나 특정 방식으로 동작하지 않습니다. C는 PC보다 비 PC 하드웨어에서 훨씬 더 많이 사용됩니다. – Olaf

+0

C로 프로그램 된 대부분의 시스템에서는 중량 라이브러리 또는 표준 라이브러리를 사용할 수 없습니다. – Olaf

관련 문제