- - PR -
オブジェクト参照がオブジェクト インスタンスに設定されていません
1
投稿者 | 投稿内容 | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-12-28 19:03
C#でunsafeにして部分的に過去の遺産のCでも実行できるようにポインタを使った行列を扱いたいのですがこのエラーが出てしまいます。ビルドはエラーを出しませんが実行時エラーとなります。わかる方ご教示いただきたく。
unsafe static void test_() { int i,j,n=5; double** A = stackalloc double *[10]; double* d = stackalloc double[10]; for(i=0;i<n;i++)for(j=0;j<n;j++) A[i][j]=0.0;//ここでエラー代入がだめ } | ||||||||||||||||||||||||
|
投稿日時: 2007-12-28 19:09
仰る意味がよく分かりません。
d を使ってないのはともかくとして。 A はポインタの配列を用意しただけでそのそれぞれのポインタはなにも指してませんね。 A[i] がなにも指してないからそれの [j] を使えません。 | ||||||||||||||||||||||||
|
投稿日時: 2007-12-28 22:40
配列を宣言して、ポインタの配列のポインタに代入しても、
・ローカルの変数 'A' をこのスコープで宣言することはできません。これは、'親またはカレント' スコープで別の意味を持つ 'P' の意味が変更されるのを避けるためです。 ・型 'double[]' を型 'double**' に暗黙的に変換できません。 とエラーが出て初期化ができません。メモリの確保についてアドバイスいただけませんでしょうか? double** A = stackalloc double*[10]; double[] a = new double[] {5,4,3,2,1}, fixed(double *A=a){for(i=0;i<n;i++) A[0][i]=a[i];} | ||||||||||||||||||||||||
|
投稿日時: 2007-12-29 02:15
興味がわきましたので試してみました。
最初は、四角形型の多次元配列を作成しようと試みましたが失敗しました。 (無理なのでしょうか?) そこで、Hongliangさんの以下の書き込み
と、未記入さんの最初の書き込み
を組み合わせて A[0] = d; という風に定義するとジャグ配列として定義できました。 (とおもいます。動いているのでこれで良いと思いますが、MSDNでunsafe多次元配列の 記述が探せなかったのでちょっと確証が持てません。) 後、既存のコードを「過去の資産」と呼ぶのであればともかく、 C言語を「過去の遺産」と呼ぶのはどうかとおもいますよ。 | ||||||||||||||||||||||||
|
投稿日時: 2007-12-29 09:13
コメントありがとうございます。
ただ、私がA[0]=d;をやったところ、構文エラーですとエラーになってしまいました。 Cを過去の遺産といったのは失言しました。既存の財産というところです。 (固有値問題のQR法のソースです。) | ||||||||||||||||||||||||
|
投稿日時: 2007-12-29 10:33
もともと stackalloc は C 言語の alloca に対応するものであって、配列ではありません。宣言の形としては配列を宣言しているようにも見えますけど。 それに多次元配列は容易に大きくなるため、限られた資源であるスタックに置くべきものではないでしょう。配列を fixed すればヒープにおいたままポインタとして扱えます。 一応、fixed な配列フィールドを持った構造体を stackalloc するとか、まず大きく stackalloc してその特定要素ごとのポインタを配列や stackalloc によるポインタのポインタとして持つとかで代用はできます。
エラーになった理由もメッセージに出てるでしょうし、あとはその構文エラーをなくすだけですね。 [ メッセージ編集済み 編集者: Hongliang 編集日時 2007-12-29 10:34 ] | ||||||||||||||||||||||||
|
投稿日時: 2007-12-29 11:59
すみません。半分わかったようなわからないような状態です。
恐れ入りますが、サンプルコードを書いていただけませんでしょうか? double[][] AA = new double[10][]; double** A = stackalloc double*[10]; fixed (double** A = (double **)&AA[0])//エラー | ||||||||||||||||||||||||
|
投稿日時: 2007-12-29 13:13
なるほど。 勉強になります。
うーむ。確かに再帰とかするとまずそうですね。 stackalloc同様、fixedを知らなかったので試してみました。
今回はジャグ配列を扱えなくなりました ![]() アクセス記述子の理解が低いので、他にもっと良い方法があるのかもしれません。 実際にCから利用する場合にはこの点が問題になることはまず無いと勝手に思ってますが。
これらも掘り下げてやってみたいところです。
私がそうでしたが、fixedキーワードについて調べて、 変数がマネージドかどうかを意識するようにすると理解が一気に進むと思います。 なお、先の"A[0]=d;"の私の書き込みではfixedは関係しません。 |
1