2

Objective-c で行列を操作するクラスを作成しようとしています。もともとは NSArrays と NSNumbers を使用していましたが、これにより、実行中のコード (二重振り子のシミュレーション) が非常に遅くなったため、再試行することにしました。配列を C++ 配列として記述しますが、解決方法がわからない問題が発生しています。

-[SMFiniteDifferenceHelper matrixHandler]: unrecognized selector sent to instance 0x100107cb0メソッドがヘッダー ファイルにあり、クラスに実装されているにもかかわらず、このコードを実行するとエラーが発生します。ただし、array[][]値の1つだけを未設定のままにしておくと、コードは正常に実行されます...

休憩

self.matrixHandler = [[SMMatrixHandler alloc] init];

        double **array1 = (double **)malloc(3*2*sizeof(double)); // height
        for (int i = 0; i < 3; ++i)
            array1[i] = new double[2]; // width

        array1[0][0] = 1.0;
        array1[1][0] = 2.0;
        array1[0][1] = 1.0;
        array1[1][1] = 0.0;
        array1[0][2] = 4.0;
        array1[1][2] = 1.0;

        NSLog(@"array 1 : \n%@",[self.matrixHandler stringForMatrix:array1 ofSize:CGSizeMake(2, 3)]);

正常に動作します

self.matrixHandler = [[SMMatrixHandler alloc] init];

        double **array1 = (double **)malloc(3*2*sizeof(double)); // height
        for (int i = 0; i < 3; ++i)
            array1[i] = new double[2]; // width

        array1[0][0] = 1.0;
        array1[1][0] = 2.0;
        array1[0][1] = 1.0;
        array1[1][1] = 0.0;
        // array1[0][2] = 4.0;
        array1[1][2] = 1.0;

        NSLog(@"array 1 : \n%@",[self.matrixHandler stringForMatrix:array1 ofSize:CGSizeMake(2, 3)]);

メソッドstringForArrayは次のようになります。

- (NSString *)stringForMatrix:(double **)m ofSize:(CGSize)s {

    NSString *string = @"";

    for (int i = 0; i < s.height; i++) {

        for (int j = 0; j < s.width; j++) {

            string = [string stringByAppendingFormat:@"%f ",m[j][i]];

        }

        string = [string stringByAppendingString:@"\n"];

    }

    return string;

}
4

2 に答える 2

1

使用法と一致しないという意味で、サイズの計算は正しくありません。このコード

double **array1 = (double **)malloc(3*2*sizeof(double)); // height

は 6 つの s 用のスペースを割り当てますdoubleが、 への 3 つのポインター用のストレージとして使用されますdouble

C コードではなく C++ コードを作成しているため、std::vectorコンテナを使用するオプションがあります。このような状況では、推奨される選択肢です。メモリを手動で管理する必要がなくなり、生の配列と同等の実行速度が得られます。

を先頭に追加#include <vector>し、次のように宣言を変更します。

std::vector<std::vector<double> > array1(3, std::vector<double>(2, 0.0));

配列を使用するコードは同じままです。

于 2013-11-06T11:05:40.063 に答える
1

問題は、6 つの double の配列を割り当てたが、それを double の配列の配列として扱うことです。あなたがそれを正しく割り当てたとしても、行は

  array1[0][2] = 4.0;
  array1[1][2] = 1.0;

インデックス 2 は3 番目のエントリであり、2項目配列の 3 項目配列を見ているため、間違っています。

コードは次のようになります。

double** array1 = new double*[3];

for (int i = 0; i < 3; ++i)
{
    array1[i] = new double[2];
}

array1[0][0] = 1.0;
array1[0][1] = 2.0;
array1[1][0] = 1.0;
array1[1][1] = 0.0;
array1[2][0] = 4.0;
array1[2][1] = 1.0;

または、次のようにするとさらに良いでしょう:

vector< vector<double> > vec(3, vector<double>(2));

vec[0][0] = 1.0;
vec[0][1] = 2.0;
vec[1][0] = 1.0;
vec[1][1] = 0.0;
vec[2][0] = 4.0;
vec[2][1] = 1.0;

編集: ベクトルの利点は、範囲外に出た場合にスローされることです。最初の例のような裸の配列は、未定義の動作を示します。

于 2013-11-06T11:14:09.553 に答える