※当サイトの記事には、広告・プロモーションが含まれます。

C言語のポインタのユースケースを知りたいだけ

gigazine.net

セキュリティ企業のKoiが、ユーザーの情報収集を目的とした126種もの悪意あるnpmパッケージを発見したことを報告しました。これらのnpmパッケージは合計8万6000回以上ダウンロードされており、AIの幻覚(ハルシネーション)を悪用する兆候も確認されたとのこと。Koiはこの攻撃手法を「PhantomRaven」と名付けています。

「AIの出力をコピペする開発者」を狙って悪意あるnpmパッケージをインストールさせて情報を盗み取る攻撃手法「PhantomRaven」の存在が判明 - GIGAZINE

⇧ Oh, my gosh...

「AI」の「幻覚(ハルシネーション)」が悪用されるとか致命的ですな...

と言うのも、残念ながら、「幻覚(ハルシネーション)」が解消される見込みが無さそうなので...

KoiはPhantomRavenの攻撃手法を踏まえて「マルウェアがセキュリティスキャンで検出されない依存関係に隠れている場合、パッケージの表示内容だけでなく、パッケージの実際の動作を監視するツールが必要となる」と述べ、自社のセキュリティ製品の有用性をアピールしています。

「AIの出力をコピペする開発者」を狙って悪意あるnpmパッケージをインストールさせて情報を盗み取る攻撃手法「PhantomRaven」の存在が判明 - GIGAZINE

⇧ 挙動を監視するってなかなか負担が大きそうですな...

10月31日は、「ハロウィン」が行われる日というイメージが強いですが、

ハロウィン、あるいはハロウィーンHalloween または Hallowe'enOíche Shamhna)は、 毎年10月31日に行われる祭りである。 カボチャやカブをくりぬいて作る「ジャック・オー・ランタン」(Jack o'lantern)を飾ったり、子どもたちが魔女お化け仮装して近くの家々を訪れてお菓子をもらったりする風習などがある

ハロウィン - Wikipedia

子供達が仮装してお菓子をねだるというスタイルはアメリカで始まり、世界各地で真似されるようになった。 名前の由来はカトリック教会の万聖節の前夜祭(All Hallow's evening→Hallow's even→Hallowe'en)とされるが、万聖節自体はローマフランク王国で7世紀~9世紀に始まり、17世紀には万霊節(11月2日)としてイングランドウェールズアイルランドで、これと似たお祝いがあった

ハロウィン - Wikipedia

ハロウィンの行事

ジャック・オー・ランタン

→詳細は「ジャック・オー・ランタン」および「ウィル・オー・ザ・ウィスプ」を参照

ジャック・オー・ランタン、あるいは、ジャック・オ・ランタンJack-o'-Lantern)は、「お化けカボチャ」「カボチャちょうちん」とも言われる。オレンジ色のカボチャをくりぬき、ナイフで目・鼻・口をつけ、内側に火のついたろうそくを立て、ハロウィーンのシンボルとなっている。

ハロウィン - Wikipedia

ハロウィンを祝う家庭では、カボチャを刻んで恐ろしげな顔や滑稽な顔を作り、悪い霊を怖がらせて追い払うため、ハロウィンの晩、家の戸口の上り段に置く。これは「ウィル・オー・ザ・ウィスプ」に由来するという説もある。その後、ワシントン・アーヴィングの短編小説「スリーピー・ホロウ」(1820年)において、首なし騎士が主人公イカボッド・クレーンに向けてカボチャを投げつける場面が描かれたことがきっかけで、ジャック・オー・ランタンを持った首なし騎士が描かれるようになり、最終的にカボチャのジャック・オー・ランタンがハロウィン及びハロウィーンのシンボルとなった。

ハロウィン - Wikipedia

⇧「ジャック・オー・ランタン」について、元々は「カボチャ」ではなく「カブ」が利用されていたらしいですな、知らなんだ...

C言語のポインタとは

Wikipediaの「ポインタ (プログラミング)」によると、

ポインタあるいはポインター(pointer)は、 コンピュータで処理するデータプログラム場所記憶して指示するレジスタ変数の分類や呼称。

ポインタ (プログラミング) - Wikipedia

概要

コンピュータは処理対象のデータと処理内容であるプログラムとを、一定の規則で記憶装置に並べて処理を行う。 記憶装置の特定の場所を指示するため、(現在のコンピュータの多くは)連続した整数のアドレス(Address)、番地を1バイト単位で割当てている。またプロセッサの内部にもレジスタと呼ばれる記憶場所を、数個から数10個程度配置している。

ポインタ (プログラミング) - Wikipedia

レジスタや記憶装置の中身は全て有限桁ビット列のデジタル数値であるが、特にアドレス指定のための数値を記憶するレジスタや、記憶装置での特定アドレス(高水準言語での特定変数)を、ポインタと呼んで区別している

ポインタ (プログラミング) - Wikipedia

⇧ とあり、ややこしい...

肝心の「C言語」の「ポインタ」はというと、

C言語のポインタ

最も典型的なポインタの例としては、C言語におけるポインタが挙げられる。C言語のポインタは「特定のメモリ領域を指し示す」ものである。ポインタを経由してメモリ上のデータにアクセスする際、参照するデータの型に応じたポインタ型を用いる。たとえば、int型のデータにアクセスする場合は、int*型を用いる。int*型を持つ変数を「intへのポインタ」(pointer to int) と呼ぶ。

ポインタ (プログラミング) - Wikipedia

C言語にポインタが存在する理由は、効率上の問題である。

ポインタ (プログラミング) - Wikipedia

C言語は、元々UNIXを記述するシステム用言語として開発されたものである。したがって、アセンブリ言語で実行できる操作のほぼ全てを行える必要があった。そのため、特定のメモリ領域への値の直接代入能力を持つなど、他のプログラミング言語と比較すると異色とも言える強力なポインタ機能を備えている。

ポインタ (プログラミング) - Wikipedia

C言語の実行モデルでは、実行プログラム上の関数コード、データが全て1次元のアドレスに直列配置される。そのため、データはおろか、関数のアドレスを取得し、他の関数にエントリーポイント情報として渡すこともできる。

ポインタ (プログラミング) - Wikipedia

また、C言語の関数では、引数は、値渡しだけをサポートし、参照渡しをサポートしない。これは、アドレスの数値を取得すれば、参照に可能な全てを行えるため、実質的に参照を数値と同一視できるからである。実際、初期のC言語では、アドレス値は、整数型互換するものとして扱われていた。これは、値と参照を明確に区別するPascalなどとは対照的である。

ポインタ (プログラミング) - Wikipedia

現在でもC言語は、void*により任意のメモリ領域にアクセスできる。なお後発のC++では参照渡しもサポートするようになった。

ポインタ (プログラミング) - Wikipedia

しかし、コード領域も含むメモリを直接扱えるということは、言語レベルでは(意図的でないとしても)不正なメモリアクセスを事実上保護できないということを示しており、C言語のプログラムにおけるポインタ関連のバグの多さがそれを証明している。

ポインタ (プログラミング) - Wikipedia

⇧ とあり、「C言語」が「アセンブリ言語」で実現できる「機能」が「要件」とする必要があったことから、「ポインタ」が必須だったということらしい。

アセンブリ言語」はというと、

アセンブリ言語アセンブリげんご、assembly languageアセンブリ)はビット列命令に対応した文字列命令を利用する低水準プログラミング言語の総称である

アセンブリ言語 - Wikipedia

アセンブラAssembler)またはアセンブラ言語Assembler Language)とも呼ばれる

アセンブリ言語 - Wikipedia

アセンブラ

アセンブルassemble)はアセンブリ言語で書かれたプログラムから機械語で書かれたオブジェクトコードへの変換である。具体的には、ニーモニックオペコードに変換しシンボル名をメモリ位置や他の実体に変換する

アセンブリ言語 - Wikipedia

⇧ とある。

このあたり、「Java」だと、

Java仮想マシン(ジャバかそうマシン、英語Java virtual machineJava VMJVM)は、Javaバイトコードとして定義された命令セットを実行するスタック型の仮想マシンAPIやいくつかのツールとセットでJava実行環境JRE)としてリリースされている。この環境を移植することで、さまざまな環境でJavaプログラムを実行することができる。

Java仮想マシン - Wikipedia

⇧「Java 仮想マシンJVMJava Virtual Machine)」などが、良しなに対応してくれているということなのかね?

細かいことは分からないのですが、「C言語」において、「ポインタ」の「機能」は必要不可欠であると。

C言語のポインタのユースケースを知りたいだけ

で、ネットの情報だと、実用的な「C言語」の「ポインタ」の活用事例についての「情報」が見当たりませんでしたと。

いまいち、「C言語」の「ポインタ」の「使いどころ(ユースケース)」が分からなかったので、「ChatGPT」氏に質問してみたところ、以下のような回答が返ってきた。

🧮 C言語のポインタ・ユースケース+再現性

# ユースケース 主な目的 典型的な使い方 再現性 備考(他言語での代替・コメント)
1️⃣ 関数で複数の値を返す(出力引数) 関数から複数の結果を返す void func(int *a, int *b) 再現可能 Pythonはタプル、GoやRustは複数戻り値、C++は参照渡しで対応可
2️⃣ 動的メモリ確保 (malloc / free) 実行時に可変サイズのデータ確保 int *p = malloc(n * sizeof(int)); 再現可能(抽象化あり) 他言語ではGCnewで自動管理。Cは明示的制御が特徴(効率重視)
3️⃣ 配列アクセス・高速データ処理 高速な走査・直接アクセス p = arr; *(p+1) ⚠️ 再現は可能だが非推奨 C++やRustも可能。Python/Goは抽象化され低速。ポインタ演算の自由度はC独自
4️⃣ 構造体の参照渡し 大きなデータのコピーを避ける void update(Point *p) 再現可能 C++は参照渡し、Go/Rustは参照(pointer/borrow)で自然に実現可能
5️⃣ 関数ポインタ(コールバック) 処理を動的に切り替える int (*cmp)(const void*, const void*) 再現可能 他言語ではラムダ・関数オブジェクト・クロージャで代替可能。ただしABI互換はC独自
6️⃣ ポインタ配列(文字列リストなど) 可変数の文字列やデータを扱う char *names[] 再現可能 他言語ではリスト・配列で同等可。Cは低レベル実装で軽量に可能
7️⃣ 多次元配列(** 可変行列構造を表現 int **matrix; matrix[i][j]; 再現可能(抽象的に) 他言語ではリストのリストで実現。ただしCでは連続メモリを確保でき高速
8️⃣ バッファ操作(文字列・バイナリ) メモリを直接読み書き memcpy(buf, src, n); ⚠️ 部分的再現 Rustのスライス、Goの[]byteC++std::spanで近いが、Cの生バッファ操作が最も自由
9️⃣ ハードウェア制御(組込み) 特定のメモリアドレス操作 volatile uint32_t *reg = (uint32_t*)0x40021000; 🚫 C特有(再現困難) Rustでも可能だがunsafe必要。Python/Goは基本的に不可能。Cが圧倒的に主流
🔟 柔軟なデータ構造(リスト・ツリー) ノードをポインタで接続 node->next 再現可能 高レベル言語ではクラス参照やスマートポインタで容易。ただしCは最も軽量実装が可能

 

何となくだが、「低レイヤー」とのやり取り以外では、「C言語」の「ポインタ」でなければいけないというわけでも無さそうなのよね...

ちなみに、

gigazine.net

⇧ 上記の対応状況が気になるところではありますが...

codezine.jp

 Linus Torvalds氏は、Linux OSのカーネルの最新バージョンである「バージョン6.1」を公開したと12月11日に明らかにした。

Linuxカーネルのバージョン6.1が公開、カーネル記述にRust言語を一部採用した最初のバージョン|CodeZine(コードジン)

 バージョン6.1は、カーネルの記述にRust言語を一部使用した最初のバージョンとなる。従来、LinuxカーネルC言語アセンブリ言語で記述していたことから、Rustの採用は大きな変化と言える。

Linuxカーネルのバージョン6.1が公開、カーネル記述にRust言語を一部採用した最初のバージョン|CodeZine(コードジン)

zenn.dev

北京郵電大学とUESTC研究者による論文「An Empirical Study of Rust-for-Linux」を読んだメモ。Linuxカーネルへの言語Rust導入(RFL)がどうなっているのか、実際のデータに基づいた分析が面白かった。

Linuxカーネルへの Rust 導入の研究論文メモ

⇧ 上記サイト様で紹介されていた論文で、「Rust」の導入に対する「課題」が取り上げられているのを見ると、「C言語」から他の「プログラミング言語」への完全な移行は厳しいような気はする...

まさに、「言うは易く行うは難し」という状況ですかね...

とは言え、「Web」系の「ソフトウェア」については、可能な限り「C言語」を脱却する方向で考えた方が良さそうですかね...

「可用性」の観点からも、「障害」が頻発するような「システム」の状態になるのは好ましくないですし...

C言語」は「カプセル化」とかも実現できない感じがして、「機能」が「密結合」し易く「変更容易性」とかも低くなりそうですしな...

止むを得ずに「C言語」を利用せざるを得ない場合を除いて、脱「C言語」していく感じになるんですかね?

そもそも、「Python」とか「PHP」とかは、「C言語」に依存した「機能」が多いので、脱「C言語」とか不可能な気はしますが...

毎度モヤモヤ感が半端ない…

今回はこのへんで。