動的メモリ管理
Compile時にsizeやlifetimeが決まらない場合にdynamic storageを使います。
動的メモリ管理とは?
Compile時にsizeやlifetimeが決まらない場合にdynamic storageを使います。
実行時サイズの配列を確保し安全に解放します。
重要なポイント
- ポインタは生存中の互換オブジェクトを指すかnullである必要があります。
- 所有するallocationは一度だけ解放します。
- ownershipとconstを明確に表現します。
CとC++のコード例
C
main.c
#include <stdio.h>
#include <stdlib.h>
int main(void) {
size_t count = 5;
int *values = calloc(count, sizeof *values);
if (!values) return 1;
for (size_t i = 0; i < count; ++i) values[i] = (int)(i * i);
printf("last=%d\n", values[count - 1]);
free(values);
return 0;
}
last=16
C++
main.cpp
#include <iostream>
#include <vector>
int main() {
std::vector<int> values(5);
for (std::size_t i = 0; i < values.size(); ++i) values[i] = static_cast<int>(i * i);
std::cout << "last=" << values.back() << '\n';
}
last=16
CとC++の比較
Cはmalloc/callocとfreeを対応させ失敗を確認します。std::vectorは所有と解放を自動化しexceptionにも安全です。
C
ownershipとcleanupはプログラマが守る規約です。
C++
containerとRAIIがownershipとcleanupをlifetimeに結び付けます。
練習課題
両方を実行して変更し、言語ごとの保証を確認します。
- nullとallocation失敗をテストします。
- AddressSanitizerとUndefinedBehaviorSanitizerを使います。
- 各pointerのownershipを文書化します。