動的メモリを使ってはいけない

2020年1月15日

組み込みソフトウェアは動的メモリと非常に相性が悪いです。

一方で、今日では常識となりつつある設計やプログラミングの技法の多くは、動的メモリの使用を前提としています。

このギャップは、意識しなければいけないところです。あなたが組み込みプログラマーなら、こういった技法は使わないか、動的メモリを避けるようにアレンジして使う必要があるかもしれません。

使ってはいけない理由

なぜそうまでして動的メモリを避けなければいけないのか。その理由をもう少し具体的に説明してみます。

1. 実行時エラーの危険がある

C や C++ では、動的メモリはプログラマーが管理しなければならないものです。そしてこのことが、ちょっとしたミスでさまざまな実行時エラー(メモリリーク・メモリ不足・不正アクセスなど)を引き起こす原因となります。これが Windows や Mac のアプリなら、プログラムがクラッシュしても多少は我慢して使ってもらえるでしょう。時間とともに次第に動きが悪くなったとしても、再起動して直るならそれで済みます。しかし、組み込みソフトウェアにそのような不安定さは許されません。

2. メモリ容量に余裕がない

組み込みで使える RAM の容量は、この現代においても、あきれるほど少ないものです。私が開発に携わった製品の一つは 3年越しのビッグプロジェクトでしたが、RAM の容量は 192KByte でした。これは、製造原価や基板面積を切り詰めなければならないという組み込み製品の特性上、仕方のないことです。この限られた容量から、グローバル変数とスタックを差し引いた分が、動的メモリに使える容量ということになります。このように余裕のない中で動的メモリを使うのは、メモリ不足という名の地雷を好んで埋め込むようなものです。

3. 処理時間が予測しにくい

組み込みソフトウェアは、プログラムの処理時間が短いことだけでなく、予測可能なこと(リアルタイム性)も同じぐらい重要視されます。たとえば、ほとんどのケースでは 1μs で終わるのに稀に 10μs かかってしまうという処理よりは、安定して 5μs で終わる処理の方が好まれたりします。new や delete の処理時間は予測がしづらく、このリアルタイム性を損ねる危険があります。

4. デバッグしにくい

製品が出荷された後でも、基板が筐体に収まった状態のまま、特定の不具合を調査しなければならないような局面があります。そこでは ICE やデバッガが使えません。このような場合、プログラム自身にメモリをダンプさせ、内部の変数やオブジェクトの状態を探るという手段がよく使われます。このとき、静的メモリにのみ依存したプログラムであればマップファイルが文字通り地図になってくれますが、動的メモリに依存すると、このようなデバッグが難しくなります。

まとめ

近代的なプログラミングの技法の多くは、動的メモリが支えています。私もプログラムを書いていて、「ここで動的メモリが使えれば」と思うことはよくあります。しかし動的メモリさえ使わなければ、ここに挙げたリスクが発現する可能性はゼロです。組み込みソフトウェアにとって、そのことで得られる安心感には計り知れない価値があるのです。