2016-12-11 6 views
4

Linuxカーネル(バージョン4.8)では、 "struct pid"は次のように定義されています(ファイル:http://lxr.free-electrons.com/source/include/linux/pid.h)。ここで "numbers [1]"(64行目)は静的配列であり、配列の大きさは1であるため、要素を1つしか持てません。配列の要素の数をコンパイル時に定義された配列のサイズより多くすることは可能ですか?

57 struct pid 
58 { 
59   atomic_t count; 
60   unsigned int level; 
61   /* lists of tasks that use this pid */ 
62   struct hlist_head tasks[PIDTYPE_MAX]; 
63   struct rcu_head rcu; 
64   struct upid numbers[1]; 
65 }; 

しかし、その後、(ファイルから:http://lxr.free-electrons.com/source/kernel/pid.c)次の行319にコード320で、アレイ "数字" が '番号[i]が' としてforループの内側にあります。変数 'i'はセグメンテーションフォルトを発生させずにゼロ以外の値を持つことができないので、どのように正しいですか?私はループ中に 'i'の値をチェックして、それが1以上になるかどうかを確認しました。はい、それでも、私はセグメンテーション・フォルトが表示されません。ここに何かがないのですか?

297 struct pid *alloc_pid(struct pid_namespace *ns) 
298 { 
299   struct pid *pid; 
300   enum pid_type type; 
301   int i, nr; 
302   struct pid_namespace *tmp; 
303   struct upid *upid; 
304   int retval = -ENOMEM; 
305 
306   pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL); 
307   if (!pid) 
308     return ERR_PTR(retval); 
309 
310   tmp = ns; 
311   pid->level = ns->level; 
312   for (i = ns->level; i >= 0; i--) { 
313     nr = alloc_pidmap(tmp); 
314     if (nr < 0) { 
315       retval = nr; 
316       goto out_free; 
317     } 
318 
319     pid->numbers[i].nr = nr; 
320     pid->numbers[i].ns = tmp; 
321     tmp = tmp->parent; 
322   } 
+1

に指定された数safety netsそれは限り、C標準に関しては「正しい」ではないのですが、それはLinuxカーネルの開発者にはほとんど関心があるがありません。それはおそらく彼らのために "働く"でしょう。 C99は 'numbers []'でこの構造を正しくサポートしていますが、LinuxではC99を使用していません。 –

+0

こんにちはKerrek、あなたの素早い返答をありがとう。それが正しくない場合、なぜそれはsegaultを与えませんか? – psin

+0

@psin:Cの何もあなたにsegfaultを保証しません。間違ったプログラムが予想どおりに動作する可能性があります。コードはおそらく意図したとおりに動作することが知られているツールでのみ構築されます。 –

答えて

0

それはコンパイル時に定義された配列のサイズ以上の配列の要素数を持つことは可能ですか?

はい。定義されていない振る舞いを呼び出すと、それを可能にするコードを書くべきではありません。

変数 'i'はセグメンテーションフォルトを発生させずにゼロ以外の値を持つことができないため、どのように正しいですか?

可能です。コードが契約を破ったからです。配列の境界外に書き込むmayが動作する可能性があります。プログラムがクラッシュする可能性があります。 未定義の振舞いです。 はその範囲外配列アクセスを防ぐためにもワンセグ障害を引き起こすことが


Cが指定されていません。そのようなアクセスはキャッチされてもされなくてもよい。コード自体は、アクセスが境界内にあることを保証する責任を負う必要があります。
training wheelsとC

+0

ありがとうございました。カーネルメインラインの安定コードがバグであることを理解することは難しいです。カーネルバージョン3.16では、配列 "numbers"は "numbers [0]"として宣言されました。要素は許可されていませんでしたが、その配列の要素にアクセスするために使用されました。 "数値"は静的な構造体配列の代わりに構造体ポインタとして使用されていますか? – psin

+0

配列 'numbers [0]'はポータブルではありません。通常、 'struct pid'のメモリは最後のフィールド(配列)が1つ以上の要素を必要とするサイズまで可能にするために追加のメモリが割り当てられます。より現代的な方法は_flexible配列を使用することです。 http://stackoverflow.com/q/11733981/2410359を参照してください。不正確なカーネルコードではなく、起こっていることが多いでしょう。 – chux

+0

...またはhttp://stackoverflow.com/q/14643406/2410359 – chux

関連する問題