2012-06-05 2 views
1

이 이 0으로 초기화 된 직후 0으로 설정된 이유를 이해할 수 없습니다.변수 i가 0으로 설정된 이유를 이해할 수 없습니까?

reinitializedvalue of k에서 i으로 프로그램이 정상적으로 작동합니다. 그러나 i0이되는 이유를 알 수 없습니다. 그리고 memset()이 배열을 지우거나 배열을 0으로 설정하는 이유는 무엇입니까?

#include <stdio.h> 
#include <stdlib.h> 
#include <windows.h> 
int main() 
{ 
    long long int i = 123456789; 
    long long int j = 987654321; 
    long long int cnt = 0; 
    int array[9] ; 
    int xyz, k, x, rem, se; 
    xyz = 0; 

// printf("I = %llf", i); 
    for (i; (i < j) && (cnt < 100000); i++) 
    { 
     k = i; 
     x = 0; 
     for (se = 0; se <= 9; se++) 
     { 
      array[se] = 0; 
     } 

/*************************************************/ 

     i = k; // Here i becomes zero. Why? 

/************************************************/ 

     //memset(array, 0, 9); 

     while(k != 0) 
     { 
      rem = k % 10; 
      for(se = 0; se <= 9; se++) 
      { 
       if(rem == array[se]) 
       { 
        xyz = 1; 
        break; 
       } 

      } 
      if(rem == array[se]) 
       { 
        xyz = 1; 
        break; 
       } 
      array[x++] = rem; 
      k = k/10; 
     } 
     if (xyz != 1) 
     { 
      cnt++; 
     // printf("Cnt = %d ", cnt); 
     // printf("The value i is = %lld\n", i); 
     // Sleep(10); 
     } 
     xyz = 0; 
     // printf("The value i is = %lld\n", i); 
     // printf("Cnt = %d \n", cnt); 
     fflush(stdin); 
    } 
    printf("The value i is = %lld \n", i-1); 
    return 0; 
} 
+4

'stdin'플러시는 정의되지 않은 동작입니다. –

+0

'array'는 9 개의 내부 위치를 가지고 있으며 10 : 0..9 (포함)에 액세스하고 있습니다. 그렇다면, 당신은'array [x]'에 접근하고,'x'는 바인딩되지 않습니다 ... –

답변

3

버퍼 오버플로가 있습니다. 버퍼가 스택에 있으므로 스택 오버플로 형식으로 간주 될 수 있습니다. .

int array[9]; // Elements array[0] .. array[8] 
... 

for (se = 0; se <= 9; se++) 
{ 
    array[se] = 0; 
} 

이것은 여분 0으로 덮어 쓰는 k이어야; ik의 값이기 때문에 0이 할당됩니다. 여기서 한 것처럼 배열의 경계 외부에 쓸 때 '정의되지 않은 동작'을 호출합니다. 정의되지 않은 동작은 아무 일도 일어나지 않아도된다는 것을 의미합니다. 때때로, 그것은 작동하는 것처럼 보일 것입니다; 때로는 예상치 못한 부작용이있을 수 있습니다. '정의되지 않은 동작'을 피하십시오.

관용적 for 루프이다

for (se = 0; se < 9; se++) 
    array[se] = 0; 

참고 대신 <=<.

의견이 일치하지 않는 사람이 있습니다. 의견을보십시오.


또한 memset()에 (주석) 호출에 대해 질문 : memset()

//memset(array, 0, 9); 

세 번째 매개 변수는 설정되는 메모리 영역의 크기 (바이트)입니다. 당신은 배열에서 총 (아마) 36 개 중 9 바이트를 설정하고 있는데, 이것은 당신이 원했던 것 같지는 않습니다.여기

는 상기 어레이는 물품 안전하고 분별하므로 동일한 기능으로 정의된다

memset(array, 0, sizeof(array)); 

array 만약 함수에 전달 된 파라미터, 즉 제대로 작동하지 않을이었다; 다른 크기가 필요합니다. 예를 들어이 점검

void somefunc(int array[], int num) 
{ 
    ... 
    memset(array, 0, num * sizeof(array[0])); 
    ... 
} 
+0

여러분의 설명이 받아 들여지지만 여전히 내가 0이되는 이유를 가정 해 봅시다. 배열 [9]이 x의 값일 뿐이라는 말입니까? –

+0

@RasmiRanjanNayak 배열의 경계가 벗어났습니다. 동작은 정의되지 않습니다. (이 경우 나는 인식을 넘어서 변경된다) – wildplasser

+0

'array [9]'요소가 없다; 유효한 배열 인덱스는'0','1', ..'8' (배열의 차원보다 하나 작음)입니다. C는 기본이 아닙니다! 배열에는 9 개의 정수가 있습니다. 첫번째는'array [0]', 두번째는'array [1]', 여덟 번째는'array [7] ', 아홉 번째와'final'은'array [8]'이다. 'array [9]'에 액세스하면, 배열 외부의 메모리에 액세스하고 있습니다. ** 배열의 일부가 아닌 ** 메모리. 'i'는'k'가 값 '0'을 가지기 때문에'0' 값이 부여됩니다. 컴파일러가있는 머신에서 배열 뒤에'k'가 저장되어 있어야합니다. 하지만 그것은 우연입니다. 그것에 의지하지 마라. –

2

배열의 끝을 덮어 쓰고 있습니다.

C에서 배열은 0부터 인덱싱되므로 루프가 한 단계 앞으로 이동합니다. 관용적 구문은 다음

말하면
for(se = 0; se < 9; se++) 

값 등의 요소의 수를 사용 <. 종종과 같이, 무서운 수치 상수를 제거하기 위해 작성 :

for(se = 0; se < sizeof array/sizeof *array; se++) 

이 당신이 array 정의를 루프를 변경하면되도록 요소의 적절한 수를 계산 (컴파일시)에 자동으로 sizeof 연산자를 사용 올바른 것으로 남아 있습니다.

1

한가지 방법은 & X 및 인쇄하여 X 및 배열 [9]의 포인터를 확인하는 & 배열 [9]를.

동일하면 꼭 언급 한대로 덮어 씁니다.

+0

예, 확실히 시도 할 것입니다. 너가 확실히 맞아. –

관련 문제