2012-03-14 4 views
0

체스 엔진을 쓰고 의사 무작위 움직임을 얻으려는 경우 이동 생성 함수에 배열을 채 웁니다.지역 변수 구조체가 범위를 벗어날 때 재설정되지 않는 이유는 무엇입니까?

...

else if(pstrcmp(input, (char*)"check", 5)){ 
      int checkIndex = getIndex(input[6], input[7] - 49); 
      printf("checkindex %i\n", checkIndex); 
      if(!(checkIndex < 0 || checkIndex > 127)){ 
       //we've received a valid check 
       struct m mUn[MOVE_BUFF]; 
       gen_psm(checkIndex, mUn); 
       int i = 0; 
       while(mUn[i].start != mUn[i].end && i < MOVE_BUFF){ 
        printf("%s\n", GSQ(mUn[i].end)); 
        i++; 
       } 
      } 
     } 

...

첫 번째 줄은 검사를 그냥 입력 : 여기에 몇 가지 코드입니다. 코드의 고기는 struct m mUn[MOVE_BUFF]과 while 루프 사이에 있습니다. 그래서 내가 만든 struct m 배열을 만들었고 특정 이동을 지정하는 몇 가지 int를 보유한 다음 확인 할 사각형의 인덱스와 채울 배열을 취하는 gen_psm에 전달합니다. 인덱스에있는 조각에 대한 유효한 이동으로 배열을 채 웁니다. 첫 번째 이동을위한 멋지고 멋쟁이. 그런 다음 두 번째 시도를 시도합니다. 배열을 처음 선언 한 곳에서 오랫동안 나가서 mUn의 범위를 벗어났습니다. 데이터를 유지하는 것은 구조체의 일부 특성입니까? 0을 채울 필요가 있습니까 (시도했을 때 0으로 채워진 것처럼 보입니다). 0으로 채워야 할 경우 더 빠른 방법이 있습니까 (0으로 채우려면 1 억 번을 채워야합니다.).

+1

'C'또는 'C++'중 하나를 지정하십시오. 함수 호출을 기반으로'C'라고 가정하고 문자열 리터럴을'char *'로 형 변환한다고 가정합니다. – Joe

+0

가능한 [로컬 변수의 메모리가 범위 외부에서 액세스 될 수 있습니까?] (http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) – fredoverflow

+0

움직임이있는 전역/정적 배열을 사용하는 것이 가장 좋을 수 있으며 스택으로 사용할 수 있습니다. 크기가 고정되어 (약 60 * 2 * 30), 범위를 벗어나는 지 확인하기 위해 몇 가지 주장을합니다. – wildplasser

답변

7

범위를 벗어난 로컬 변수의 메모리가 변경된다는 것을 보장하는 표준은 없으며 단순히 읽기만하면 정의되지 않은 동작입니다. 컴파일러는 0 일 수도 있고, 그렇지 않을 수도 있으며, 시작 부분에 스마일을 삽입 할 수도 있습니다. 변수가 범위를 벗어나면 그 메모리 위치에 어떤 일이 일어나는지에 대해서는 명시되어 있지 않습니다.

단순히 배열을 선언하면 공간이 예약되지만 각 멤버가 초기화되지는 않습니다. memset을 사용하거나 각각의 루프를 초기화 할 수 있습니다.

+0

예. 또는이 프로그램의 동작을 설명하는 것 : 새로운 로컬 변수를 작성해도이 변수가 지워지지는 않습니다. 그것들은 그 mamory 위치에 어떤 값이 있는지를 가지고 있습니다./그리고 동일한 루틴을 두 번 실행하면, 두 번째로 생성 된 로컬 변수는 처음과 동일한 메모리 주소를 얻을 수 있습니다. –

1

데이터가 삭제된다는 보장은 없으며 성능 향상을 위해 범위를 종료 할 때 지워지지 않습니다.이를 읽거나 수정하기위한 정의되지 않은 동작 일뿐입니다.

디버거의 경우 POISON 마커로 페이지를 채워 valgrind의 memcheck와 같은 범위를 벗어나는 액세스를 확인할 수 있습니다.

1

컴파일러가 사용하지 않는 메모리로 수행 할 작업을 보장 할 수 없습니다. 일반적으로 혼자 남겨 둡니다. 메모리를 초기화하려면 으로 초기화해야합니다. memset()을 사용하면 메모리의 큰 부분을 효율적으로 0으로 설정할 수 있지만 소유하지 않은 메모리는 건드리지 않도록하십시오.

2

시도

struct m mUn[MOVE_BUFF] = {0}; 

+0

나는 {{0}}'이라고 말할 필요가 있다고 생각합니다. –

0

진짜 대답은 (당신은 단순히 'm'보다 당신의 구조체에 대한 더 나은 이름을 선택 할 수 있습니다) "왜 자신을 다시 것?" 메모리를 초기화하지 않은 경우 정의되지 않은 상태입니다. (첫 번째 실행에서 16 진수 0이 될 수 있다는 사실은 사용자가 전혀 의지 할 수있는 것이 아닙니다.)

분명히 플러시해야합니다.

는 지금까지 ... 음, 그것에 대해 이동하는 가장 빠른 방법으로

memset 함수 내 첫 번째 시도 될 것이다. 그게 너무 느리다면 아마도 같은 크기의 더미 구조를 만들고, null로 채우고 memcpy를 로컬의 맨 위에 놓습니다. 못 생겼어.하지만 네가 그보다 빠른 것을 얻지는 않을거야.

관련 문제