문제

이것이 멍청한 질문이라면 죄송합니다 :(.

C 코드의 조각.

int array[5];
int cnt;

for(cnt = 0; cnt <= 10; cnt+=1)
{
      array[cnt] = cnt;
}

오류를 주어야합니까? 아니! 잘 작동합니다! 하지만 왜 그게? 첫 번째 줄에서 이중 크기 (11) 이상의 배열이 정의 된 것 같습니다. 나중에 배열 [5 ~ 10]에 액세스 할 수도 있습니다. 그리고 그것은 나를 혼란스럽게합니다. 배열을 정의 할 때 작동이 중지됩니다 [4 이하] ...

미리 감사드립니다.

도움이 되었습니까?

해결책

특정 컴파일러 및 컴퓨터에서 작동하는 경우가 있지만 계산해서는 안됩니다.

C 언어 사양에 따른 코드의 동작은 한정되지 않은. 이것은 당신이 희망하는 일을 할 수 있거나 컴퓨터가 충돌 할 수 있음을 의미합니다. 코를 날아가는 악마.

Java 및 C#과 같은 고급 언어와 달리 C는 귀하를 신뢰하며 배열 한계에 대한 명시 적 검사를 수행하지 않습니다. 당신은 배열의 경계를 벗어난 책임이 없어야합니다.

다른 팁

"Works"의 정의가 "아직 충돌하지 않은"것과 동의어 인 경우이 "작품"만 있습니다.

당신이보고있는 것은입니다 정의되지 않은 행동, 유효하지 않은 인덱스로 배열에 액세스하여 발생합니다. 정의되지 않은 행동은 프로그램을 포함하여 모든 일이 발생할 수 있음을 의미합니다.

"하지만 왜 그런가요?"

그것이 C의 방식이기 때문입니다.

배열 경계는 실행 시간에 점검되지 않습니다.

그것이 "C의 법칙"입니다.

나는이 모든 것이 실제로 정의되지 않았다는 것을 지적하고 싶습니다. 두 변수 모두 스택에 있기 때문에 예제는이 특정 예제에서 "작동"합니다. 이것이 CNT의 주소는 배열 끝 바로 아래에 있습니다. CNT가 CNT == 5에 도달하면 명령문 배열 [CNT] = CNT; 배열 전용 메모리에 쓰기가 아니라 CNT의 주소가 놓여있는 곳에 바로 작성됩니다. 카운터를 바꾸지 않는 것은 행운입니다. CNT> 5가 쓰레기에 대한 메모리가 없으면 "스택 void"(적절한 단어를 모르면)에만 쓸 것입니다.

이것을 설명하는 또 다른 예 :

int main(int ac,char **av)
{
    int a[5];
    int cnt;
    int cnt2=3;

    for(cnt=0;cnt<7;cnt++) {
        a[cnt]=cnt;
        printf("%d %d %d\n", a[cnt], cnt, cnt2);
    }
}

산출:

0 0 3
1 1 3
2 2 3
3 3 3
4 4 3
5 5 5
6 6 5

마지막 두 가지는 루프에 대한 쓰기가 [] 후에 스택 데이터를 덮어 쓰고 매우 혼란스러운 오류를 일으킬 수 있습니다. 이 경우 CNT2는 쓰레기가 져 있습니다.

C의 배열은 런타임에 확인되지 않습니다. 다시 말해, 크기 n 배열을 "정의"하고 배열 끝에서 행복하게 액세스 할 수 있습니다. 배열 끝을 벗어나면 스택 (또는 힙)의 어딘가에 메모리를 버립니다.

어딘가에 메모리를 버리면 프로그램이 충돌 할 가능성이 높습니다. 이러한 충돌은 실제로 배열의 끝을 넘은 곳에서 멀리 떨어져있을 수 있기 때문에 추적하기가 어려울 수 있습니다.

일반적으로 C로 배열을 선언 할 때는 배열의 크기를 표시하기 위해 일종의 상수 또는 #Define을 사용하는 것이 가장 좋습니다.

#define MAX_ELEMENTS 10
int array[MAX_ELEMENTS];
int cnt;
for(cnt = 0; cnt < MAX_ELEMENTS; cnt+=1) {
   array[cnt] = cnt;
}

배열 할당에서 Max_Elements를 지나면 CNT의 값을 덮어 쓸 수 있습니다. 다른 변수를 덮어 쓸 수 있습니다. 모두 컴파일러와 코드 구조에 따라 다릅니다. 또한 <로그인 for 루프의 사용에 유의하십시오. C 배열은 0 기준이므로 적은 수준 이하의 사용을 확인해야합니다.

C의 배열 경계 반드시 그런 것은 아닙니다 런타임에 확인되었습니다. 표준 잎 도구는 그들이 선택했는지 여부를 자유롭게 할 수 있습니다. 한정되지 않은. 뚱뚱한 포인터가있는 구현에서 샘플은 실제로 일종의 오류를 유발할 수 있습니다.

배열의 끝을 실행하면 소프트웨어가 힙을 기대하지 않고 손상시키는 메모리를 덮어 쓰고 있습니다. 귀하의 소프트웨어는 계속 실행될 수 있지만 매우 불안정 할 것입니다!

스택 메모리가 어떻게 포장되는지에 따라 다릅니다. 또한 행복하게 그 값을 덮어 쓰고 읽을 수도 있지만 스택을 손상시킬 가능성이 높습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top