문제

나는 최근 NSLOG 에서이 이상한 행동을 추적하는 약 30 분 동안 낭비했다.

NSString *text = @"abc";
long long num = 123;
NSLog(@"num=%lld, text=%@",num,text); //(A)
NSLog(@"num=%d, text=%@",num,text); //(B)

줄 (a)는 "num = 123, text = abc"를 인쇄하지만 (b) 라인 (b) "num = 123, text =를 인쇄합니다.(없는)".

분명히 인쇄 a long long ~와 함께 %d 실수이지만 누군가가 왜 그런 원인을 설명 할 수 있습니까? text NULL로 인쇄하려면?

도움이 되었습니까?

해결책

스택에서 메모리 정렬을 엉망으로 만들었습니다. X86 프로세서가있는 최신 Apple 제품을 사용하는 것보다 가정합니다. 이러한 가정을 고려하여 스택을 고려하여 두 상황 모두에서 마치 다음과 같습니다.

   |      stack          | first | second |
   +---------------------+-------+--------+
   |        123          |       |  %d    |
   +---------------------+ %lld  +--------+
   |         0           |       |  %@    |
   +---------------------+-------+--------+
   |   pointer to text   | %@    |ignored |
   +---------------------+-------+--------+  

첫 번째 상황에서는 스택 8 바이트와 4 바이트를 입습니다. 그리고 NSLOG보다 스택 12 바이트 (8 바이트 %lld 그리고 4 바이트 %@).

두 번째 상황에서는 NSLOG에게 먼저 4 바이트를 가져 오도록 지시합니다 (%d). 변수는 8 바이트 길이이고 실제로 적은 숫자를 보유하기 때문에 상위 4 바이트는 0이됩니다. 그러면 NSLOG가 텍스트를 인쇄하려고 할 때 nil 스택에서.

메시지를 보내는 이후 nil OBJ-C에서 유효합니다 NSLOG는 방금 보내집니다 description: 에게 nil 아마 아무것도 얻지 못한 다음 인쇄 (null).

결국 Objective-C는 추가로 C이기 때문에 발신자는이 혼란을 정리합니다.

다른 팁

Varargs가 구현되는 방법은 시스템 의존적입니다. 그러나 발생하는 것은 논쟁이 크기가 다를 수 있지만 인수는 버퍼에 연속적으로 저장된다는 것입니다. 그래서 처음 8 바이트 (그것이 크기라고 가정합니다. long long int논쟁의)는이다 long long int, 그리고 다음 4 바이트 (시스템의 포인터 크기라고 가정)는 다음과 같습니다. NSString 바늘.

그런 다음 함수를 기대할 때 int 그리고 포인터는 처음 4 바이트가 int (그것이 크기라고 가정합니다 int) 그리고 다음 4 바이트는 포인터가 될 것입니다. 귀하의 시스템에 대한 논쟁의 특정 엔지니어와 배열로 인해 long long int 숫자의 가장 중요한 바이트가되므로 123 인쇄를 인쇄합니다. 그런 다음 객체 포인터의 경우 다음 4 바이트를 읽습니다. a로 해석되었습니다 nil 바늘. 실제 포인터는 결코 읽지 않습니다.

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