Arduino C 코드에서 메모리 오버플로 오류를 발견하는 방법은 무엇입니까?


10

Arduino에 코드를 업로드 한 후 직렬 모니터에서 의심스러운 출력을 얻었습니다. 공백의 영원한 출력 또는 갑자기 문자열 또는 스크램블 된 문자열과 같이.

Arduino IDE에 컴파일 오류 또는 경고가 없기 때문에 Arduino가 고장 났다고 생각했지만 일부 테스트 후 Arduino IDE 컴파일러가 모든 종류의 오류를 포착하지는 않습니다. 이것은 짧은 시간 내에 Arduino를 충돌시키는 것 같습니다.

Arduino IDE에 표시되지 않는 오류를 어떻게 알 수 있습니까?

답변:


10

MEMORYFREE 라이브러리는 메모리 사용과 위험을 찾을 수 있습니다.

예:

#include <MemoryFree.h>

// On Arduino Duemilanove with ATmega328:
//
// Reported free memory with str commented out:
// 1824 bytes
//
// Reported free memory with str and Serial.println(str) uncommented:
// 1810
//
// Difference: 14 bytes (13 ascii chars + null terminator)

// 14-bytes string
//char str[] = "Hello, world!";


void setup() {
    Serial.begin(115200);
}


void loop() {
    //Serial.println(str);

    Serial.print("freeMemory()=");
    Serial.println(freeMemory());

    delay(1000);
}

MemoryFree가 스택 포인터를 설명하는지 잘 모르겠습니다. 스택 포인터가 힙 포인터와 충돌하면 분할 오류가 발생할 수 있습니다.


7

RAM 소진의 가장 일반적인 원인은 String 객체를 사용하거나 많은 상수 문자 배열 (c 스타일 문자열)을 사용하는 것입니다.

IDE 1.0.4에는 문자열 객체를 오랫동안 괴롭힌 malloc에 ​​대한 수정 사항이 포함되어 있습니다.

RAM을 줄이려면 다음과 같은 상수 문자열로 낭비하십시오.

Serial.print("Hello World");  // This consumes RAM!

F () 매크로를 사용할 수 있습니다. 이 매크로는 문자 배열을 PROGMEM에 유지시킵니다. 배열을 사용하면 1 바이트의 메모리 만 사용됩니다.

Serial.print(F("Hello World"));  // Keeps the character-array in PROGMEM

PROGMEM에 저장된 문자열은 런타임 중에 변경할 수 없습니다.

디버거 나 메모리 컨트롤러없이 검색이 진행되는 한, 구식 탐정 기법을 사용하여 문제가 발생한 위치를 찾아야합니다.


1
유용한 답변에 감사드립니다! IDE 지원 메모리 디버거가 실제로 없습니까?
powtac

1
이것은 오래된 질문이지만, atmel ATmega MCU에 적합한 디버거가 있습니다 . arduino 툴체인과 "IDE"는 기본적으로 장난감이기 때문에 arduinos 에는 디버거가 없습니다 .
코너 울프

1
실제로 F ()에 대한 힌트는 RAM에서 수백 바이트를 절약했습니다!
powtac

1
포함 된 문자열과 함께 F ()를 사용할 때 컴파일 오류가 발생합니다 //. :-(
powtac

Arduino 1.5.7에서이 컴파일 오류가 발생합니다 ...
powtac

3

여기서 메모리 누수 / segfault 유형의 런타임 오류에 대해 이야기하고있는 것 같습니다.

이미 작성된 코드에서 이러한 오류를 발견 할 수있는 방법은 없습니다 (코드를주의 깊게 살펴 보지 않는 한). 그러나 코드 를 작성 하는 동안 이러한 일이 발생하지 않도록하는 것은 매우 쉽습니다 . 루프 나 재귀 호출을 작성할 때 매우주의하십시오. 스스로에게 "이것이 손에서 벗어날 수 있습니까?"라고 물어보십시오. 이것이 "손에 닿지 않는"범위 인 것처럼 보이면이를 방지하기위한 코드를 작성하십시오.

segfaults 정보-배열 인덱스의 경계 값을 확인하면 괜찮습니다. 포인터를 사용하는 경우 포인터 산술에주의하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.