2

我正在尝试编写一个类来在 Objective-c 中操作矩阵,最初我使用的是 NSArrays 和 NSNumbers,但是这导致我正在做的事情的代码非常慢(模拟双摆)所以我决定尝试重新将我的数组写为 c++ 数组,但是我遇到了我不知道如何解决的问题。

-[SMFiniteDifferenceHelper matrixHandler]: unrecognized selector sent to instance 0x100107cb0即使我的方法在头文件中并在类中实现,运行此代码也会给我一个错误。但是,如果我只保留其中一个array[][]值未设置,则代码运行良好......

休息

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 个双精度的数组,但将其视为一个双精度数组。即使您分配正确,这些行

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

错误,因为索引 2 是第三个条目,并且您正在查看 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 回答