2010-08-10 8 views
3

왜 항상 모든 용도에 맞게 크기가 고정 된 버퍼를 스택에 할당 할 수있을 때 alloca()를 사용하고 싶습니까? 이것은 수사학적인 질문이 아닙니다 ...alloca()는 어떤 경우에 유용합니까?

+1

도 볼 http://stackoverflow.com/questions/1018853/why-is-alloca-not-considered-good-practice –

+0

'goto'는 나쁜 습관으로 간주되지만 때로는 필요합니다. alloca()가 필요합니까? –

답변

2

버퍼 크기가 런타임에 달라 지거나 가끔씩 만 필요한 경우 유용 할 수 있습니다. 이는 각 호출에서 고정 크기 버퍼보다 ​​전체 스택 공간을 덜 사용합니다. 특히 함수가 스택 또는 재귀 적으로 높은 경우.

+1

가장 확실한 대답은 +1입니다. 함수가 재귀적일 때 스택에 가능한 최대 버퍼 크기를 할당하면 최대 재귀 호출 수를 상당히 줄일 수 있습니다. 따라서 alloca()를 사용하면 최악의 시나리오를 처리해야하는 불이익을 줄일 수 있습니다. –

+0

더 자세히 설명해 주시겠습니까? – KodeWarrior

0

결코 C++의 일부가 아니며 C에서는 유용하지 않습니다. 그러나 "정적 버퍼를 스택에"할당 할 수는 없습니다 - 정적 버퍼는 컴파일 타임에 할당되고, 스택에 없습니다.

alloca()의 포인트는 물론 고정 크기가 아니며 스택에 있으며 함수가 종료 될 때 자동으로 해제됩니다. C++과 C 모두이 문제를 처리 할 수있는 더 나은 메커니즘을 가지고 있습니다.

+2

static은 threadsafe가 아니며 alloca는 – user411313

+0

질문을 편집 했습니까? 이제는 "고정 크기"가 아닌 "고정 크기"로 읽습니다. – Shog9

+0

alloca는 C에서보다 C++의 일부가 아니며 둘 다 표준화되지 않았습니다. –

0

컴파일 할 때 필요할 수있는 최대 크기를 알 수없는 경우에 사용하는 것이 좋습니다.

이든이든 another question이든간에 이것은 표준이 아니며 스택 오버플로가 발생할 수 있는지 여부를 판단 할 방법이 없습니다.

+0

* 스택 오버플로! –

0

어떤 경우에는 alloca()가 유용합니까?

내가 사용하는 alloca가 Open Dynamics Engine에만 사용 된 것을 본 적이 있습니다. AFAIK 그들은 그것으로 거대한 행렬을 할당하고있었습니다 (그래서 컴파일 된 프로그램은 100MB 스택을 필요로 할 수 있습니다). 함수가 반환 될 때 자동으로 해제됩니다 (smartpointer ripoff처럼 보입니다). 이것은 꽤 오래 전이었습니다.

아마도 새로운/malloc보다 훨씬 빠르지 만 여전히 나쁘다고 생각합니다. RAM 프로그램을 정중하게 실행하는 대신 화면이 처리하기에 너무 복잡해 졌을 때 스택 오버플로로 인해 오류가 발생할 수 있습니다 (예 : 오해의 소지가 있음) 좋은 행동은 아닙니다. IMO, 특히 물리 엔진에있어서, 누군가가 수천 개의 벽돌을 씬에 던져 버릴 것을 쉽게 예상 할 수 있으며, 동시에 모든 충돌이 일어날 때를 볼 수 있습니다. 또한 수동으로 스택 크기를 설정해야했습니다. 즉 RAM이 더 많은 시스템에서는 프로그램이 여전히 스택 크기에 의해 제한됩니다.

모든 용도에 적합한 크기의 고정 크기 버퍼가 스택에 있습니까? 이것은 수사학적인 질문이 아닙니다 ...

모든 용도로 고정 된 크기의 버퍼가 필요한 경우 정적/전역 변수에 넣거나 힙 메모리를 사용할 수도 있습니다.

+1

"smartpointer"ripoff로서, 나는 alloca가 아이디어를 훔치기 위해 타임머신을 사용했다고 생각한다. 'alloca'는 1960 년대 후반이었고 똑똑한 포인터는 1986 년 이후입니다 ... 정적/전역 변수가 공유하지 않는 alloca의 긍정적 인 점은 threadsafety에 대한 다른 곳에서 지적되었습니다. 힙은 사용 방법에 따라 다르므로 900 문자로 처리하지 마십시오. –

+0

@Heath Hunnicutt : "alloca는 타임 머신을 사용했습니다"Open Dynamics Engine은 60 년대에 작성되지 않았습니다. – SigTerm

0

alloca() 함수는 사실상 필요하지 않습니다. 메모리 할당 목적으로 C에서 malloc()/free() (또는 C++의 가능성 집합 중 하나)을 사용하여 거의 동일한 실제 효과를 얻을 수 있습니다. 이것은 더 작은 스택 크기에 더 잘 대처할 수 있다는 장점이 있습니다.

그러나 I 보았 [1]의 하나 합법 (해키 경우!) 사용 : 윈도우에 전위 스택 오버 플로우를 검출; 할당량 (액세스하려는 슬롭 공간의 양)이 실패하면, 당신은 벗어 났지만 정상적으로 회복하기에 충분한 공간이 있습니다. __try/__except으로 감싸 지므로 충돌이 발생하지 않았으며 gcc로 인한 문제를 피하기 위해 추가 어셈블러 트릭이 필요했습니다. 내가 말했듯이, 해킹.그러나 내가 본 중에 alloca()에 유일하게 유효한 용도 인 영리한 제품입니다.

하지만 그렇게하지 마십시오. 그런 게임이 필요없는 코드를 작성하는 것이 좋습니다.


[1] 그것은 티클 8.4 (및 티클의 가능성이 이전 버전)이었다. 이후 버전에서는 제거되었습니다. 최신 버전은 그것이 까다 롭고, 까다 롭고 깊이 까다로웠 기 때문에 제거했습니다. 8.6에서는 그런 종류의 펑키가 아닌 실행 엔진의 스택없는 구현을 사용합니다.

+0

FWIW : Windows에서는 일반적으로 스택 끝에 동적으로 확장하는 데 사용되는 가드 페이지가 있습니다. 스택의 한계에 도달하고이 가드 페이지가 히트하면 예외가 발생하지만 한 번만 발생합니다. 스택 끝을 감지 한 후 가드 페이지를 재설정하지 않으면이 트릭은 한 번만 작동합니다 ... 다음 번에 프로그램이 시스템에 의해 즉시 종료됩니다. – Shog9

+0

@Shog : 우리가 더 이상 필요로하지는 않지만 흥미 롭습니다. 우리는 구현 엔진이 어떻게 C 스택이 더 이상 필요하지 않게 작동하는지 전환했습니다. :-) 나는 방금 malloc에 ​​의해 중복 될 수없는 alloca에 대한 사용으로서 사람들에게 흥미로울 것이라고 생각했다. –

+0

동의합니다 - 공유해 주셔서 감사합니다! – Shog9

0

당신이 (다른 메모리 할당 ++ C 또는 new, 또는) malloc()를 사용할 수없는 경우 신뢰성, 또는 합리적인 될 수있다 alloca()를 사용하지만, 당신이 당신의 스택에 사용 가능한 공간이있다 가정 할 수있다 - 즉, 정말 아무것도 할 수 없을 때. glibcsegfault.c 예를 들어

, 우리가 가진 :

/* This function is called when a segmentation fault is caught. The system 
    is in an unstable state now. This means especially that malloc() might 
    not work anymore. */ 
static void 
catch_segfault (int signal, SIGCONTEXT ctx) 
{ 
    void **arr; 

    /* ... */ 

    /* Get the backtrace. */ 
    arr = alloca (256 * sizeof (void *)); 

    /* ... */ 
} 
관련 문제