2017-09-26 6 views
0

저는 현재 내 필요에 맞는 Arduino 코드의 일부를 적용하고 있습니다. 다음 코드는 나를 혼란 :이 변수를 스택에 저장하지 않으려면 어떻게해야합니까?

// Dont put this on the stack: 
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN]; 

는 스택에 buf 변수를 넣어 무엇을 의미합니까? 이 작업을 어떻게 피할 수 있습니까? 내가 그렇게하면 어떤 나쁜 일이 일어날 수 있겠습니까?

+1

이 주석은 배열이 자동 저장 기간 대신 정적 저장 기간을 가져야한다는 것을 의미한다고 생각합니다. 네임 스페이스에서 선언하거나 컨텍스트에 따라 정적 지정자가있는 로컬 배열로 선언 할 수 있습니다. –

+1

'RH_RF95_MAX_MESSAGE_LEN'의 크기와 사용 가능한 스택의 크기에 따라 ... 기다릴 수 있습니다 ... Stack Overflow. – user4581301

답변

4

프로그램 스택의 크기가 제한되어 있습니다 (데스크톱 컴퓨터에서도 일반적으로 메가 바이트 단위로 제한되며 Arduino에서는 훨씬 작을 수 있음).

함수의 모든 함수 로컬 변수는 LIFO 방식으로 저장됩니다. main 메서드의 변수는 스택의 맨 아래에 있으며, 그 위에는 main이라는 함수의 변수가 있습니다. 공간은 (일반적으로) 함수를 입력 할 때 예약되며 함수가 반환 될 때까지 다시 계산되지 않습니다. 함수가 매우 큰 버퍼를 할당하면 (또는 호출 체인의 여러 함수가 약간 더 작은 버퍼를 할당하는 경우) 스택 제한에 빠르게 접근 할 수 있으므로 프로그램이 중단 될 수 있습니다.

배열이 외부에 할당되어있는 것처럼 들리며, 함수를 전역 범위에 두었습니다. 단점은 공유 버퍼가 하나 밖에 없다는 것입니다 (두 개의 함수가 액세스를 조정하지 않으면 동시에 사용할 수 없지만 스택 버퍼는 각 함수에 대해 독립적으로 예약됩니다).하지만 스택에 비용이 들지 않습니다 그걸 써; 그것은 프로그램 메모리의 별도 섹션 (일반적으로 제한이 없거나 적어도 메가 바이트 범위가 아닌 기가 바이트의 제한이있는 섹션)에서 할당됩니다.

그래서 귀하의 질문에 대답 :

는 스택에 buf 변수를 넣어 무엇을 의미합니까?

  1. 기능 범위가 아닌 전역 범위에 선언하고, 그 당신보다 더 복잡하지만
  2. static (또는 thread_local으로 선언되지 않은 :이 경우

그것은 스택에있을 것입니다 지금 당장 걱정해야한다.); 이 기능 범위에 static을 선언 않다면, 그것은 단지 특정 기능 내가이 일을 피할 수있는 방법

에서 직접 참조 할 수있는 글로벌 메모리는 기본적으로인가?

기능 범위에서 큰 비 - static 배열을 선언하지 마십시오.

내가 그렇게하면 어떤 나쁜 일이 벌어 질 수 있습니까?

배열의 크기가 충분하면 사용 가능한 스택 공간이 부족하여 스택 오버플로가 발생하여 프로그램이 충돌 할 수 있습니다.