本当は関数の中でfloat[p][p]とやりたいところですが。。。

[戻る]
K.O. 2002/09/23(月) 09:06:36
VC++6で使っています。

@
H(float *Dat, float *HAT, int p)
 {
  float Al[p][p]; 
   :::::::::
 とやりたいところですが、下記のコンパイルエラーです。直接Mainから通って来た
 pと言うパラメータをそのまま、行列の配列として使いたいのですが、どうすればいいのでし
ょうか?

C:\O\A\B.c(20010):error C2466: サイズが 0 の配列を割当てまたは宣言しようとしました
C:\O\A\B.c(20010):error C2057: 定数式が必要です。
C:\O\A\B.c(20010):error C2466: サイズが 0 の配列を割当てまたは宣言しようとしました
C:\O\A\B.c(20010):error C2087: '<Unknown>' : 添字が不正です。

関数内で、
float  *Al;
として、
Al = (float *) malloc(p*p, sizeof(float));
とするのがよいのでしょうか?


A
その場合、中でAlを使い終わった後、
メモリを解法するために
free (Al);
とすると、
デバッグ中、そこにさしかかったとたん、
DebugErro! Program:C\O\A\Debug\B
Damage: afterNormal block (#19) at 0x00
(Press Retry to Debug the Application)
というエラーが出てそこで止まってしまいます。

何がいけないのでしょうか?


B
勿論freeをしないとそこは通るのですが、
それをやらないことによる副作用と言うのはあるでしょうか?



宜しく、お願い致します。

アイススケーター 2002/09/23(月) 09:37:36
>Al = (float *) malloc(p*p, sizeof(float));

これは
Al = (float *) malloc(p*p*sizeof(float));
の間違いではないですか?

↑のようにしたら特に問題はなかったようですが・・・

YuO [E-Mail] 2002/09/23(月) 09:49:16
とりあえず,丸囲み数字はUnicode系以外の文字コードを使う場合は利用厳禁です。
#Windows以外では化けます。JIS X0208外の文字ですから。

>(1)
>   float Al[p][p];
> とやりたいところですが、下記のコンパイルエラーです。直接Mainから通って来た
> pと言うパラメータをそのまま、行列の配列として使いたいのですが、どうすればいいのでし
>ょうか?

C89やC++では,配列の要素数は定数でなければいけません。
つまり,変数であるpを使うことはできません。
#C99(ISO/IEC 9899:1999)ではこの制限は存在しません。

というわけで,Code WarriorとかのC99対応コンパイラを使うのが一番簡単な解決策だったりします。

それはおいといて……。


C++使って,
std::vector<std::vector<float> >(p, std::vector<float>(p));
ってやるのが一番楽ですね。
#そこはかとなくWrite Only Codeのニオイが漂いますが……。


> 関数内で、
> float  *Al;
> として、
> Al = (float *) malloc(p*p, sizeof(float));
> とするのがよいのでしょうか?

float ** Al;
で,とりあえずsizeof(float *) * pバイトのメモリを確保後,
Al[0]にsizeof(float) * p * pバイトのメモリを確保して,
Al[n]がAl[0] + p * nになるように設定してやればいいです。

でもって,解放時にはAl[0]とAlを解放することになります。

このあたりは二次元配列で検索をかけてみるとよいでしょう。


>(2)
> デバッグ中、そこにさしかかったとたん、
> DebugErro! Program:C\O\A\Debug\B
> Damage: afterNormal block (#19) at 0x00
> (Press Retry to Debug the Application)
> というエラーが出てそこで止まってしまいます。

恐らく範囲外アクセスを行ったのでしょう。
Releaseでやってたら,ヒープ構造を壊していたところですよ。


>(3)
> 勿論freeをしないとそこは通るのですが、
> それをやらないことによる副作用と言うのはあるでしょうか?

使い方次第です。
流れを完全に制御できていて,freeする必要がないのであればfreeしなくてもよいですが,
何度通るかわからないとか,大量のメモリを使うのであればfreeする必要があります。
#メモリリークによってエラーが起きても気にしないなら別ですが。

K.O. 2002/09/23(月) 12:14:26
YUOさん、アイススケーターさん
ありがとうございます。

そうすると、

float  **Al;
Al = (float *) malloc(p*sizeof(float));
Al[0] = (float *) malloc(p*p*sizeof(float));

n行m列の要素は、
Al[n*p+m]で使い、
解放は

free(Al[0]);
free(Al);

これでいいでしょうか?

float  *Al;
Al = (float *) malloc(p*p*sizeof(float));
:::::
free(Al);
か
float  *Al;
Al = (float *) malloc(p*p, sizeof(float));
:::::
free(Al);
ではまずいのでしょうか?

YuO [E-Mail] 2002/09/24(火) 00:25:27
> float  **Al;
> Al = (float *) malloc(p*sizeof(float));
> Al[0] = (float *) malloc(p*p*sizeof(float));
> n行m列の要素は、
> Al[n*p+m]で使い、

過去ログ見ました?
float **Al;
とした場合,
Al = malloc(p * sizeof(float *));
Al[0] = malloc(p * p * sizeof(float));
で,アクセスには
Al[n][m]
のように使います。
#上記は,C++ならvectorが使えるのでCのコード。


> 解放は
> free(Al[0]);
> free(Al);

こちらはこれでよいです。


> float  *Al;
> Al = (float *) malloc(p*p*sizeof(float));
> :::::
> free(Al);

これを使う場合は,一次元を二次元のようにして扱う場合です。


> float  *Al;
> Al = (float *) malloc(p*p, sizeof(float));
> :::::
> free(Al);
> ではまずいのでしょうか?

こちらはダメ。まず,mallocの使い方がわかっていません。

古いスレッドには追加発言できません。