0

2次元配列の形式の行列を使用してカーブフィッティングプログラムを作成していますが、コンパイラはスレッド1:EXC_BAD_ACCESS(code = 1、address = 0x13f800000)などのBAD_ACCESSエラーをランダムにスローします。プログラムは時々動作し、他の時にはクラッシュします。任意のアイデアをいただければ幸いです。ありがとう。

- (void)main {
    NSLog(@"Enter size");

    scanf("%i", &matrixSize);

    float* temp;

    matrix = (float**)calloc(matrixSize, sizeof(float*));
    temp = (float*)calloc(matrixSize+1, sizeof(float));

    for (int i = 0; i < matrixSize+1; i++) {
        matrix[i] = temp + (i*(matrixSize+1));
    }

    [self enterPoints];
    [self elimination];
    [self setNeedsDisplay:YES];
    free(matrix);
    free(temp);
}

//points entered here

- (void)enterPoints {
    CGPoint *points = (CGPoint *)malloc(matrixSize * sizeof(CGPoint));

    for (int i = 0; i < matrixSize; i++) {
        scanf("%lf", &points[i].x);
        scanf("%lf", &points[i].y);
    }

    for (int j = 0; j < matrixSize; j++) {
        for (int i = 0; i < matrixSize+1; i++) {
            if (i == (matrixSize)) {
                matrix[i][j] = points[j].y;
            }
            else {
                matrix[i][j] = pow(points[j].x, (matrixSize-1)-i);
            }
        }
    }
    free(points);
}

//matrix reduction occurs here

- (void)elimination {

    for (int j = 0; j < matrixSize; j++) {
        double divideValue = matrix[j][j];
        for (int i = 0; i < matrixSize+1; i++) {
            matrix[i][j] /= divideValue;
        }
        for (int j1 = 0; j1 < matrixSize; j1++) {
            if (j1 == j) {
                if (j1 == matrixSize-1) {
                    break;
                }
                else {
                    j1++;
                }
            }
            double subValue = matrix[j][j1];
            for (int i = 0; i < matrixSize+1; i++) {
                matrix[i][j1] -= matrix[i][j]*subValue;
            }
        }
    }
}

//drawing the polynomial 

- (void)drawRect:(NSRect)dirtyRect {
    NSGraphicsContext * GraphicsContext = [NSGraphicsContext currentContext];
    CGContextRef context = (CGContextRef) [GraphicsContext graphicsPort];

    CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 1.0);

    CGContextSetLineWidth(context, 3.0);

    CGContextMoveToPoint(context, 0, matrix[matrixSize][0]*100 + 100);

    [GraphicsContext saveGraphicsState];

    CGMutablePathRef path;

    path = CGPathCreateMutable();

    for (float i = -matrixSize; i < matrixSize; i+=.01) {
        float y = 0;

        for (int j = 0; j < matrixSize; j++) {
             y += matrix[matrixSize][j]*pow(i, j);
        }

        CGContextAddLineToPoint(context, i*100 + 100, y*100 + 100);   
    }

    CGContextStrokePath(context);

    [GraphicsContext restoreGraphicsState];
}
4

2 に答える 2

1

マトリックスに十分なメモリを割り当てていません。この行はデータ領域全体を設定しますが、次matrixSize+1の代わりに要素のみを割り当てていますmatrixSize*(matrixSize+1)

temp = (float*)calloc(matrixSize+1, sizeof(float));

したがって、matrixSize+1列とmatrixSize行を維持します。

matrix = (float**)calloc(matrixSize, sizeof(float*));
temp = (float*)calloc(matrixSize * (matrixSize+1), sizeof(float));

for (int i = 0; i < matrixSize; i++) {
    matrix[i] = temp + (i*(matrixSize+1));
}

後で使用するときは注意してください。あなたはそれを間違って扱っています:

for (int j = 0; j < matrixSize; j++) {
    for (int i = 0; i < matrixSize+1; i++) {
        if (i == (matrixSize)) {
            matrix[i][j] = points[j].y;
        }
        else {
            matrix[i][j] = pow(points[j].x, (matrixSize-1)-i);
        }
    }
}

iに行きmatrixSize+1ますが、それを行インデックスとして使用していることに注意してください(matrixSize行のみがあります)。matrix[j][i]の代わりに使うつもりだったと思いますmatrix[i][j]。これは、初期マトリックスを作成するときにも行いますが、実際には、割り当てに合わせて変更しました。

したがって、プログラムには2つのバッファオーバーランがあります。

于 2012-10-24T21:10:03.303 に答える
0

EXC_BAD_ACCESSは、オブジェクトの1つがメソッドを呼び出す前に、オブジェクトの1つがオーバーリリースされていることを示します(ガベージコレクションと混同しないでください)。収集されたオブジェクトでメソッドを呼び出すコード内のポイントに到達すると、ポインターは無効なメモリ位置を参照しています。

ゾンビオブジェクトを見つけるには、これを見てください:XCodeでNSZombieを有効にする方法

私はこれを使用しましたが、非常にうまく機能します。

于 2012-10-24T21:07:25.420 に答える