2016-01-24 3 views
0

Я пытаюсь случайным образом заполнить массив 2d со значениями, а затем умножить их, но по какой-то нечетной причине, когда я запускаю свой код, на последней итерации я получаю ошибку сегментации. Я попытался уменьшить число, которое я передаю, и все, но ошибка по-прежнему сохраняется. Вот код, который я пытаюсь выполнить, любая помощь очень ценится, спасибо.Сегментация Неисправность последней итерации

#include <stdlib.h> 
#include <stdio.h> 

int main(int argc, char *argv[]) 
{ 

    FILE *matrixFile; 
    int n = atoi(argv[1]); // the number of matrices 
    int i, j; // must declare outside of for loop due to resolve C99 mode error 
    double arrA[n][n];// = CreateRandomMatrix(n); 
    double arrB[n][n]; 
    double sumArr[n][n]; 
    matrixFile = fopen("home/acolwell/Documents/CPE631_HW2_Number1/results.txt", "w+"); 

    printf("Usage: %s <size of nxn matrices>\n", argv[1]); 

    // randomly populate arrA and arrB 
    for(i = 0; i < n; i++) 
    { 
     printf("%d\n", i); 
     for(j = 0; j < n; j++) 
     { 
      printf("%4d", j); 
      arrA[i][j] = (double)rand()/(double)RAND_MAX; 
      arrB[i][j] = (double)rand()/(double)RAND_MAX; 
     } 
    } 

    printf("Exiting Matrix randomization"); 

    // multiply the matrices and write them to the file 
    for(i = 0; i < n; i++) 
    { 
     for(j = 0; j < n; j++) 
     { 
      sumArr[i][j] = arrA[i][j] * arrB[i][j]; 
      printf("Writing matrix "); 
      fprintf(matrixFile, "%0.3lf\n", sumArr[i][j]); 
     } 
    } 

    if(matrixFile) 
    { 
     fclose(matrixFile); 
    } 

    matrixFile = NULL; 

    return 0; 
} 
+1

Насколько я знаю, в C вы не можете использовать непостоянный значение при создании массива. – cdonts

+1

@ cdonts Да, вы можете. Он называется 'VLA' [массив переменной длины] и поддерживается с c99, IIRC –

+0

@CraigEstey Полезно знать! – cdonts

ответ

1

Эта ошибка будет связана с записью конца вашего массива или невозможностью открыть файл. Я хотел бы предложить работает GDB, чтобы проверить вашу программу, когда он работает, но с быстрым взглядом Интересно, если вы не значит иметь

"/home/acolwell/Documents/CPE631_HW2_Number1/results.txt" 

как файл, чтобы написать вместо

"home/acolwell/Documents/CPE631_HW2_Number1/results.txt" 

Я бы предложил проверить результат вашего вызова fopen перед вызовом fprintf.

+0

Спасибо, иногда это просто требует дополнительный набор глаз ...... Я чувствую себя довольно плохо, потому что это было что-то очень простое. – user3596586

+0

Обычно это и дополнительный набор глаз или попытка объяснить это кому-то, как правило, требуется, чтобы найти его. Это происходит со всеми нами. –

0

Я только что скомпилировал и протестировал ваш код. Имя файла, которое вы указываете, неверно; вам нужно «/» перед «домом».

Не уверен, что эти требования, но написать matrixFile как матрица: добавить новую строку после каждой строки матрицы «размножается», а не после каждого элемента:

for(i = 0; i < n; i++) { 
    for(j = 0; j < n; j++) { 
     sumArr[i][j] = arrA[i][j] * arrB[i][j]; 
     printf("Writing matrix "); 
     fprintf(matrixFile, "%0.3lf ", sumArr[i][j]); 
    } 
    fprintf(matrixFile, "\n"); 
} 

Кроме того, серьезно относитесь к высказыванию Крейга Исли. Переполнение стека может произойти, даже вне помещения этого веб-сайта;) Рассмотрите возможность распределения вашей матрицы динамически в куче.

1

Если n достаточно большой, вы создадите переполнение стека с помощью VLA. Я проверил это экспериментально с вашим кодом (например, используйте n из 5000).

Итак, вам нужно использовать malloc для выделения из кучи. Но для этого потребуется немного переписать.

Вот способ использовать выделение кучи и получить выгоду от VLA [используя некоторые незначительные фокусы]:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define C(_arr) (double (*)[(size_t)(n)]) _arr 

void 
docalc(FILE *fout,int n,double arrA[n][n],double arrB[n][n],double sumArr[n][n]) 
{ 
    // must declare outside of for loop due to resolve C99 mode error 
    int i, 
    j; 

    // randomly populate arrA and arrB 
    for (i = 0; i < n; i++) { 
     printf("%d\n", i); 
     for (j = 0; j < n; j++) { 
      printf("%4d", j); 
      arrA[i][j] = (double) rand()/(double) RAND_MAX; 
      arrB[i][j] = (double) rand()/(double) RAND_MAX; 
     } 
    } 

    printf("Exiting Matrix randomization"); 

    // multiply the matrices and write them to the file 
    for (i = 0; i < n; i++) { 
     for (j = 0; j < n; j++) { 
      sumArr[i][j] = arrA[i][j] * arrB[i][j]; 
      printf("Writing matrix\n"); 
      fprintf(fout, "%0.3lf\n", sumArr[i][j]); 
     } 
    } 
} 

int 
main(int argc, char *argv[]) 
{ 

    FILE *matrixFile; 
    int n = atoi(argv[1]);    // the number of matrices 

    printf("Usage: %s <size of nxn matrices>\n", argv[1]); 

    matrixFile = fopen("/tmp/results.txt", "w+"); 
    if (matrixFile == NULL) { 
     perror("fopen"); 
     exit(1); 
    } 

    double *arrA = malloc(sizeof(double) * n * n); 
    double *arrB = malloc(sizeof(double) * n * n); 
    double *sumArr = malloc(sizeof(double) * n * n); 

    docalc(matrixFile,n,C(arrA),C(arrB),C(sumArr)); 

    if (matrixFile) 
     fclose(matrixFile); 

    matrixFile = NULL; 

    return 0; 
} 
+0

Что ?! no 'free()' s? Богохульство! – e0k

+0

Проверено, что это работает с 'n = 5000'. – e0k

+0

@ e0k Да, и я не проверял 'malloc' для' NULL'. Так что [egads!], Двойное богохульство ... :-) Для меня я вообще не делаю 'free' от' main', потому что это немного спорный момент, так как программа немедленно прекратится [и на самом деле быстрее _не делать их - особый случай]. Если бы я делал 'malloc' внутри библиотечной функции [, которая называлась' docalc'], я бы сделал 'free' –

Смежные вопросы