2013-02-22 2 views
-2

에서 배열의 요소에 액세스 나는이 기능이 있습니다부정적인 인덱스

void func(int index, struct foo b[]) 
{ 
    // ... 
    a[0][0] = b[index].c[0]; 
    // ... 
} 

을하지만 때로는 함수가 인덱스 -2로 호출 : 범위를 벗어났습니다

a[0][0] = b[-2].c[0]; 

내가 -2 생각, 때로는 추락하지만 때때로 그렇지 않습니다.

배열 b의 선두 주소가 0xffd9cda4 인 경우 b [-2]의 가중치는 무엇입니까?
0xffd9cda4 + 0xfffffffe = 0x1ffd9cda2? 0x1ffd9cda2가 유효합니까?

Linux 64 비트에서 실행됩니다.

+10

너는 생각한다 * -2는 범위를 벗어 났습니까? – adamdunson

+1

정확하게이 목표를 달성하기 위해 노력하고 있습니까? – adamdunson

+0

'b'의 종류는 무엇입니까? 당신 같은 배열 (모호하게)이라면, 질문은 논박의 대상입니다. 그렇지 않은 경우 더 많은 코드를 보여주십시오. 어떻게 선언됩니까? 초기화되었거나 할당 되었습니까? –

답변

2

주소가 &b[0] 인 메모리 블록을 차지하는 배열이 b입니다. b[-2]의 주소가 무엇인지 알아 내려고하지 마십시오. 분명히이 배열이 차지하는 메모리 블록 내에 있지 않기 때문입니다.

배열 범위 밖의 메모리에 액세스하려고하면 정의되지 않은 동작가 생성됩니다.

*(b - 2) 

void func(int index, struct foo b[]) { 
    // ... 
} 
0
b[-2] 

가 동일 :


또한이 기능의 몸체 내에 배열 b의 사이즈를 취득 할 수없는 점에 유의 분명히 틀린 것입니다. 정의되지 않은 동작, 소유하지 않은 메모리 액세스. UB는 프로그램이 작동하지 않을 것이라는 의미는 아니며 프로그램의 동작이 정의되지 않았 음을 의미합니다..

+0

@ casper1314 : 그게 무슨 뜻인지 모르겠군요. –

+0

시나리오는 입니다. void func (int index, struct foo b []) { ... a [0] [0] = b [index] .c [0]; ... } 때때로 함수가 index = -2로 호출되었습니다. 언젠가 충돌이 일어나기도하고 때로는 충돌 할 수도 있습니다. 그리고 테스터에게 재현하는 방법을 알려주고 수정이 효과적이라면 시도해야합니다. IDE에서 b : 0xffd9cda4, index : 0xfffffffe (-2) 행을 볼 때 실행됩니다. 그런 다음 b [index]가 어느 메모리 범위로 갔는지보고 싶습니다.이 메모리 범위를 재현하기 위해 몇 가지 일반적인 단계를 찾을 수 있는지 확인하고 싶습니다. How do you say 어떻게해야합니까? – casper1314

+0

@ casper1314 : * 정의되지 않은 동작 *입니다. 항상 충돌을 일으키는 것은 아닙니다. 기간. 이제 문제를 진단했습니다. 해결 방법은 배열 경계 외부의 액세스를 중지하고 사양을 테스트하는 것입니다. 추가로 이동해야 할 경우 인덱스를 기록하고 잘못된 인덱스가 전달되는 상황을 재현하여 유효하지 않은 인덱스가 로그에 나타나지 않도록하십시오. –

2

경계 외부의 배열에 액세스하면 정의되지 않은 동작이 발생합니다. 그러나 C에는 자동 배열 범위 검사가 없습니다. 그래서 이것은 충돌을 일으킬 수 있지만 그것이 보장 될지는 아무 것도 없습니다. 흔히 메모리에 인접 해있는 객체에 오버플로되는 경우가 있습니다.

b이 배열이 아닌 포인터 인 경우 b[-2]이 유효 할 수 있습니다. 예 :

typedef struct foo { 
    int c[5]; 
} foo_struct; 
foo_struct x[10]; 
foo_struct *b = &x[3]; 

이제 할 경우

a[0][0] = b[-2].c[0]; 

가 상당의 일에 :이 경우

a[0][0] = x[1].c[0]; 

관련 배열 범위는 x의 것들이다.

+0

* "잘못된 인덱스 (음수 또는 너무 높음)가있는 배열에 액세스하면 충돌이 발생할 수 있지만"* - 보장 할 수는 없지만 그러한 일을하는 것이 ** 정의되지 않은 동작을 생성한다는 것이 보장됩니다. * 따라서 피해야합니다. – LihO

+0

@LihO 왜 가끔씩 충돌하는지에 대한 그의 질문에 대답하려고 노력했지만 항상 그런 것은 아닙니다. – Barmar

+0

네, 이해합니다. 나는 그가 메모리에이 방법으로 접근하는 것에 의지 할 수 없다는 명확한 진술이 있어야한다고 생각한다. – LihO