2016-07-18 4 views
0

Я пытаюсь написать массив (2x20000) на C. тестовый код:Объявление массива: C вина Сегментация

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

double test(int smod) 
{ 
// 
// test subroutine 
// 
double vect_fma[2][20000]; 
int i; 

// write on file // 
FILE *f = fopen("file.txt", "w"); 
/////////////////// 

    for(i = 1; i < 20001; i = i + 1){  
    // allocate the vector for the fma analysis 
    vect_fma[1][i] = i*smod; 
    vect_fma[2][i] = i*smod; 
    if (i%smod == 0) 
    fprintf(f, "%f %f %f \n", 1.0*i, vect_fma[1][i],vect_fma[2][i]); 
}  
    fclose(f); 
    return 0; 
} 


int smod; 
void main() 
{ 
    smod = 10; // every 10 print the output 
    test(smod); // call the function 
} 

я скомпилированный код с gcc test.c -lm -o test и я получил Segmentation fault (core dumped).

Насколько я знаком с C, я понимаю, что «the compiler tries to store it on the stack» и решение может быть представлено на связанной странице .... но это решение выглядит довольно странно (и сложно понять) по сравнению с более простую fortran-декларацию массива real(8), dimension(n:m) :: vect_fma, которую я могу поставить в подпрограмму или в функцию без проблем. Возможно, что объявление, которое я написал в коде, похоже на fortran real(8), dimension(n,m),allocatable :: vect_fma?

Итак, вопрос заключается в том, что в C существует более простой способ объявить массив внутри функции? Огромное спасибо всем.

+0

Вероятно, слишком большой для стека - вместо этого используйте кучу –

+0

@EdHeal что-то вроде этого '2d_array = (int *) malloc (sizeof (int) * N * M);'? –

+0

Получали ли вы ошибку сегментации во время компиляции (что, по вашему мнению, ваш ответ) или во время выполнения? – CorbinMc

ответ

2

У вас есть доступ к границам в нескольких местах, то есть undefined поведение. В C индекс массива находится в диапазоне от 0 до N-1, а не от 1 до N. Это означает, что переписав часть цикла в:

for(i = 0; i < 20000; i = i + 1){  
    // allocate the vector for the fma analysis 
    vect_fma[0][i] = i*smod; 
    vect_fma[1][i] = i*smod; 
    if (i%smod == 0) 
     fprintf(f, "%f %f %f \n", 1.0*i, vect_fma[0][i],vect_fma[1][i]); 
}  

Возможно 2x20000 двойников может быть слишком большим для размера стека на вашей системе, вы бы лучше фиксируя неопределенные поведения первого и посмотреть, если проблема исчезнет.

+0

спасибо за ваш ответ, что было правильно в отношении целых чисел и спасибо за отправленный пример. Я перепутал с fortran, который начинается с 1 до 20000, что означает, что у меня 20000 элементов, вместо этого в C мне нужно начинать с 0 до 20000. –

+0

От 0 до 19999 не 20000, потому что '<20000' – Michi

2

Проблема в вашей петле for. Вы должны начать с итерации, где i=0 и закончите с итерацией, где i=19999. Ваш код начинается с итерации, где i=1 и заканчивается итерацией, где i=20000.

Проблема в том, что нет 20000-го элемента вашего массива, всего 19999 (нулевой индекс). Когда вы получаете доступ к 20000-му элементу, ваша системная память доступа, которая никогда не была выделена для вашей программы, которая вызывает ошибку сегментации.

Закрепите свою петлю, и вы должны быть хорошими.

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