ポインタとメモリ

動的メモリ管理

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を文書化します。