source

'&'을 'scanf' 문에 넣지 않으면 어떻게 됩니까?

factcode 2023. 9. 16. 09:55
반응형

'&'을 'scanf' 문에 넣지 않으면 어떻게 됩니까?

저는 인터뷰를 하러 갔었고, 그 자리에서 다음과 같은 질문을 받았습니다.

다음 사항에 대해 어떻게 생각하십니까?

int i;
scanf ("%d", i);
printf ("i: %d\n", i);

나는 이렇게 대답:

  • 프로그램이 성공적으로 컴파일됩니다.
  • 번호를 잘못 인쇄하지만 충돌하지 않고 끝까지 실행됩니다.

제가 했던 대답이 틀렸습니다.저는 압도당했어요.

그 후 그들은 나를 해고했습니다.

프로그램이 충돌하여 코어 덤프로 이어질 수 있습니다.

프로그램이 중단되는 이유를 이해할 수 없었습니다.누가 이유를 설명해 줄 수 있습니까?어떤 도움이든 감사히 받겠습니다.

변수가 정의되면 컴파일러는 해당 변수에 대한 메모리를 할당합니다.

int i;  // The compiler will allocate sizeof(int) bytes for i

i위에서 정의된 것은 초기화되지 않았으며, 불확정한 값을 가지고 있습니다.

에 된 에 를 과 에 할당된 해당 메모리 것.i. 즉 의 해야 를 해야 를 의 .

scanf("%d", &i);

글을 쓸 것int리의터에 할당된 메모리 위치에 사용자의 i.

한다면&지음 앞에 배치되지 .i,그리고나서scanf된 데이터를 .력를리에다할고다l할y고oee력를리aeni에 대신에&iSince .부터i는 불확정 값을 포함합니다. 메모리 주소의 값과 동일한 값을 포함하거나 메모리 주소의 범위를 벗어나는 값을 포함할 수 있습니다.

어느 경우든 프로그램이 비정상적으로 동작하여 정의되지 않은 동작을 초래할 수 있습니다.그럴 경우엔 무슨 일이 생길 수도 있습니다.

정의되지 않은 행동을 불러일으키기 때문입니다.scanf()의는과에한를다e다를한annror의는f에s과이"%d"지정자를 찾았습니다.어떤 정수의 주소로 해석될 수 있는 정수를 전달하고 있지만 전달되지 않습니다.이것은 표준에 정의된 동작이 없습니다.실제로 컴파일되지만(그러나 경고가 발생합니다) 예상치 못한 방식으로 작동할 것이 분명합니다.

코드에는 또 다른 문제가 있습니다.i변수는 초기화되지 않으므로 불확실한 값을 갖지만 정의되지 않은 동작의 또 다른 이유가 됩니다.

표준은 다른 유형이 예상되었을 때 지정된 유형을 통과할 때 발생하는 일에 대해 아무것도 언급하지 않습니다. 이는 어떤 유형을 스왑하든 정의되지 않은 동작일 뿐입니다.그러나 이 특정 상황은 포인터를 정수로 변환할 수 있기 때문에 특별한 고려 사항에 해당하지만 동작은 포인터로 다시 변환하고 정수 유형이 값을 올바르게 저장할 수 있는 경우에만 정의됩니다.이것이 컴파일하는 이유인데, 확실히 제대로 작동하지 않습니다.

의 를 했습니다 했습니다 )int*되지만,int() ~로)로 .scanf(). 이렇게 하면 정의되지 않은 동작이 발생합니다.

정의되지 않은 행동에 대해서는 어떤 일도 일어날 수 있습니다.프로그램이 충돌할 수도 있고 충돌하지 않을 수 있습니다.

일반적인 환경에서는 운영 체제에서 쓰기가 허용되지 않는 위치를 가리키는 일부 "주소"가 다음으로 전달되면 프로그램이 중단될 것으로 예상됩니다.scanf() 것은 프로그램을입니다. , ② ③ ④ OS ⑤ ⑥ ⑦ 됩니다 로 하게 을 에 은 됩니다 로 하게

한 에서 이 하지 는 에서 에서 는 이 sizeof (int) != sizeof (int*) 이 한 으로 된 된 으로 한 이 ,scanf다른 변수나 반환 주소의 일부를 집어삼킬 수 있습니다.반환 주소를 변경하면 보안 취약성이 발생할 수 있습니다.

* 나는 어셈블리어 전문가가 아니니까, 이것을 좀 과장되게 받아들이세요.

프로그램이 중단되는 이유를 이해할 수 없었습니다.누가 이유를 설명해 줄 수 있습니까?어떤 도움이든 감사히 받겠습니다.

조금 더 적용될 수도 있습니다.

int i = 123;
scanf ("%d", &i);

첫번째 명령으로 메모리를 하나의 정수 값에 할당하고 이 메모리 블록에 123을 씁니다.이 블록에 어리에가다고해이다e해고rss를ksys가'ytes어0x0000ffff을 메모리 에 씁니다. 을 을 에 으로 에 을 으로 0x0000ffff 있기 에 -의지기에조에e( ( )i하지만 주소입니다.

명령을 사용하는 경우scanf ("%d", i);대신 당신은 메모리 주소에 입력을 쓰고 있습니다. 123(네, 네, 네.) 그렇게 되면 도 있습니다.분명히 그것은 심하게 잘못되어 충돌을 야기할 수 있습니다.

(표준에서 요구하는) scanf에 &(ampersand)가 없기 때문에, 우리가 값을 입력하는 즉시 프로그램이 갑자기 종료됩니다. 프로그램에 몇 줄의 코드가 더 쓰여지든 상관없이 말입니다.

-->> 실행해보니 코드 블록에 그것이 있었습니다.

우리가 터보 컴파일러에서 실행한다면 스캔프 이후의 모든 라인을 완벽하게 실행할 수 있지만, 우리가 알고 있는 것처럼 내가 인쇄한 값은 쓰레기가 될 것입니다.

결론:- 일부 컴파일러에서는 실행되지만 일부 컴파일러에서는 실행되지 않으므로 유효한 프로그램이 아닙니다.

언급URL : https://stackoverflow.com/questions/34557160/what-will-happen-if-is-not-put-in-a-scanf-statement

반응형