문제

다음 코드를 고려하십시오.

void populate(int *arr)
{
   for(int j=0;j<4;++j)
       arr[j]=0;
}

int main()
{
   int array[2][2];
   populate(&array[0][0]);
}

코드가 유효한지 여부에 관계없이 지역 사회에서 이것에 관한 논의가있었습니다 (그 이름을 언급해야합니까?). 한 사람은 UB가 위반되어 UB를 호출한다고 말하고있었습니다.

C ++ 표준 ($ 5.7/5 [expr.add])

"포인터 피연산자와 동일한 배열 객체의 요소 또는 배열 객체의 마지막 요소에 대한 결과가 모두있는 경우 평가는 오버 플로우를 생성하지 않아야합니다. 그렇지 않으면 동작이 정의되지 않습니다."

그러나 나는 코드에 아무런 문제가 없다. 코드는 나에게 완벽하게 괜찮다.

그래서이 코드가 유효한지 알고 싶습니까? 내가 뭔가를 놓치고 있습니까?

도움이 되었습니까?

해결책

당신의 array 두 배열입니다 int[2], 당신의 기능을하는 동안 populate() 그것을 단일 배열로 취급합니다 int[4]. 컴파일러가의 요소를 정렬하기로 결정한 방법에 따라 array, 이것은 유효한 가정이 아닐 수 있습니다.

구체적으로, 언제 j 2이고 액세스하려고합니다 arr[2], 이것은 바깥쪽에 있습니다 main'에스 array[0] 따라서 유효하지 않습니다.

다른 팁

배열 배열이 있습니다. array[1] 다음 array[0] 메모리에서는 배열이 인접하기 때문에. 만약에 p == array[0], 그 다음에 p[1] 다음 p[0], 배열은 인접하기 때문에. 그래서, 당신은 옳습니다 : 모든 기억 array 인접합니다.

사진에서 array 이렇게 보인다.

+-----------------+-----------------+
|      [0]        |      [1]        |
+-----------------+-----------------+

이제 고장합시다 array[0] 그리고 array[1], 그들은 개별적으로 다음과 같이 보입니다.

+--------+--------+
|  [0]   |  [1]   |        
+--------+--------+

따라서 마지막 그림은 다음과 같습니다.

+--------+--------+--------+--------+
| [0][0] | [0][1] | [1][0] | [1][1] |
+--------+--------+--------+--------+

이제 문제는이 연속 메모리에 자신의 방식으로 액세스 할 수 있다는 것입니다. 정답은, 표준에 의해 보장되지 않습니다. 배열은 인접하지만 표준으로 인해 수행 한 방식을 색인화 할 수 없습니다. 다시 말해:

&array[0][0]+2 == &array[1][0], 하지만 (&a[0][0] + 2) + 1 정의되지 않은 반면 &a[1][0] + 1 유효합니다. 이것이 이상하게 보이면, 그것은 당신이 표준에서 게시 한 견적에 따라, 당신은 배열 내부에 있거나 배열을 지나서 최대 하나의 포인터를 계산할 수 있습니다 ( "One Past"포인터를 디포링하지 않고). .

실제로, 나는 이것이 어디서나 실패 할 것이라고 의심하지만 표준에 따르면 적어도 정의되지 않은 동작으로 인해 코드가 유효하지 않습니다.

보다 이 게시물에 있습니다 comp.lang.c 또한.

그것은 항상 작동하지 않을 것입니다. C에는 2D 배열이 아닌 배열 배열이 있습니다. 서브 디 어레이가 항상 메모리에서 인접한 것으로 지정되는 것은 아닙니다 (정적 배열은 C/C ++ 표준을 확인할 수 있음)이 특정 예에서는 올바르게 작동한다고 생각합니다. 그러나 Malloc (또는 신규)이 서브 사업을 상당히 멀리 떨어 뜨렸을 수 있기 때문에 메모리를 동적으로 할당했다면 실패 할 것입니다.

그러나 '2D'메모리를 선형으로 걸어 가려면 1D 배열에 대해 2D 액세서를 구축 할 수 있으며 잘 작동하며 Memset과 같은 것들이 1D 배열에 대해 작동합니다.

~ 안에 C 모든 것은 선형 메모리 세그먼트에 저장됩니다. 당신은 주소를 통과하고 있습니다 a[0][0] 주소와 동일합니다 a[0] 그래서a[i][j] 동일합니다 a[i*ColSize+j] 모든 것이 선형으로 저장되어 있기 때문입니다. 그러나 메모리를 동적으로 할당하면 모든 행이 인접한 위치에 저장되지 않기 때문에 실패합니다. 그 다음에 a[i][j] 할 것입니다 *(&a[i]+j).

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