2012-08-10 4 views
4

좋아, 분명히이 작품 :Objective-C의 가변 크기 배열?

void foo(size_t s) { 
    int myArray[s]; 
    // ... use myArray... 
} 

이 정말 합법적입니까? 컴파일해야하기 때문에 (C 컴파일러가 비상 계적으로 그것을 거부 할 것입니다) 말입니다. 내 질문의 첫 번째 부분은 어떻게 작동합니까? 스택에 할당한다고 가정합니다. 이것은 alloca()과 다른가요? 이 작품

void bar(size_t chunkSize) { 
    CFReadStreamRef foo = NULL; 
    // ...some stuff to init foo... 

    while (stuffToDo) { 
     UInt8 buffer[chunkSize]; 
     // ...read some data from stream into buffer 
     // using CFReadStreamRead()... 
    } 
} 

:

실제로, 나는이 작업을 수행하는 코드를 발견했다. 그러나 루프 내부에서 함수의 첫 번째 줄 (바로 앞에 foo이 선언 됨)에 버퍼 할당을 이동하면 함수가 작동을 멈 춥니 다. 디버거에서는 로컬 변수에 대한 첫 번째 액세스를 얻은 후 종료됩니다. 나는 던져진 예외를 보지 않는다. 충돌하지 않는다. 단지 프로그램이 계속 실행된다. (실제로 함수는 문자열을 반환하고 반환 값은 반환 변수가 초기화되는 값인 NULL이다. 나는 무슨 일이 일어나고 있는지 잘 모르겠습니다. 내 질문의 두 번째 부분은, 첫 번째 부분에 비추어 볼 때, 도대체 무슨 일이 벌어지고 있는가?

답변

3

C99에서는 위험하지만 예 - 이것은 alloca과 비슷합니다.

alloca와 비슷하기 때문에 스택에 할당 할 때 합리적인 크기의 배열이 필요합니다. 길이가 0 인 경우 이것이 정의되어 있는지 잘 모르겠지만 배열이 '충분히 커야'그렇게하면 스택 오버플로가 발생할 수 있습니다.

무슨 일이 일어나고 있는지 - 크기가 합리적이라면 루프 밖으로 당겨도 아무런 차이가 없어야합니다. 매개 변수 값이 너무 큽니다 (또는 아마도 0) 때문에 정의되지 않은 동작이 발생하는 것 같습니다. chunkSize 매개 변수의 유효성을 검사해야합니다. 어셈블리는 루프에서 꺼내는 것이 왜 효과가 있는지 말해 줄 것입니다 (프로그램의 다른 모든 것이 잘 형성되었다고 가정).

+0

분명히. 그리고 나는 그것이 위험하다는 것을 말한 일부 소식통을 발견했으며, 분명히 그렇습니다. 하지만 어떻게 위험하고 올바르게 사용하는지 이해하고 싶습니다. –

+0

(위의 대답으로 이동) – justin

+1

@ jeffamaphone : 왜냐하면'char foo [some_large_value]'는 스택을 매우 잘 날릴 수 있기 때문입니다. 이 기능이 존재할 이유가 없습니다. –