ZigのArrayListにポインタ安定性ロックが追加、メモリ安全性を向上

Zig: Pointer Stability for ArrayLists

Zigの標準ライブラリに、ArrayListのポインタ安定性を保証するロック機構が追加された。これは2024年にHashMapに導入された手法をArrayListに拡張したもので、開発者は要素へのポインタを保持する際にlockPointers()を呼び出し、不要になったらunlockPointers()で解放する。これにより、リストの再割り当てによるポインタの無効化を検出し、デバッグを容易にする。実際のバグ例とその修正方法、ArrayList特有の注意点(順序変更操作によるポインタ移動)も解説されている。

ポインタ安定性の前提が破られた場所を、スタックトレース付きのパニックで即座に教えてくれる。
  1. amluto

    これは弱いように思えます。

    Rustのような言語では、コンパイラがポインタを「ロック」してくれて、忘れることがありません。

    C++(そしておそらくZig)のような言語では、理論上は少なくとも、動的配列のストレージを参照するイテレータやスライスに、ストレージを固定する何らかのロックを保持させることができるでしょう。

    しかし、このAPIでは、プログラマがポインタをロックすることを覚えておく必要があり、また、正しいコード領域に対してロックを保持し続ける必要があります。そして、私の目には、ブログ記事の例でさえ、ロックが安定性を必要とする関数の完全に外側で取られており、ロックのスコープを正しくするものが何もないように見えます。型システムでさえ助けにはなりません——問題のparse関数は、ポインタロックされたArrayListパラメータを要求することを宣言できません。

  2. _bohm

    素晴らしい機能ですが、コレクション内のアイテムへの安定したポインタが必要なら、ArrayListは間違ったデータ構造ではないかという気がしてなりません。誰か、単にインデックスを保存するのではなく、これを使う例を教えてくれる人はいませんか?あるいは、Unrolled Linked List(Zigでは0.16で削除されるまでSegmentedListと呼ばれていた、なぜ削除されたのかはわかりませんが)を使うこともできるでしょう。

  3. portly

    これは言語の他の部分と一貫していると考えると、非常に理にかなっています。これは、自分のプログラミングエラーを検出するためにコードにトリップワイヤーを仕掛けるもう一つの方法です。関数でアサートを使って入出力を検証するのと似ています。

    私はArrayListをよく使うので、これをコード全体に追加して強化できるのは楽しみです。

    これが誰にでも好まれるわけではないとは想像できますが、そうでなければ、他の明示性も楽しめないでしょう。

  4. Rendello

    余談:Rustで本当に恋しいZigの(構文)機能が2番目のコードブロックに示されています。それは、次のような接頭辞付きの複数行文字列リテラルです:

    const text =

    \\これは長いコメントです

    \\しかし、行を任意に分割できます

    \\そしてインデントを維持できます。

    ;

    私はRustのマクロライブラリ`docstr` [1]を使い始めました。これも同じことをします:

    const TEXT: &'static str = docstr!(

    /// これでRustでもできます。

    /// 長いテキストでは、このスタイルをよく好みます。

    );

    これはマクロでも動作します(ドキュメントの例):

    let greeting: String = docstr!(format!

    /// こんにちは、私の名前は{name}です。

    /// 私は{}歳です!

    age

    );

    1. https://docs.rs/docstr/latest/docstr/

  5. boricj

    コンテナ内のポインタ変更に対するアサートであり、SDLサーフェスのようなデータ構造のロック/アンロックではないと理解するのに少し時間がかかりました。

    最近、パスのコンポーネントを反復処理できるカスタムC++コンテナを実装しましたが、std::stringをバックエンドにしていました。インデックスと文字列への参照を保存するだけで、std::stringが変更後に再割り当てされてもイテレータが無効になりません。わずかなコストで、はるかにエラーが少なくなります。

この日のほかの記事

2026-08-30