Программа компилируется без ошибок, но не выполняет функцию присваивания массива C lang - PullRequest
0 голосов
/ 21 января 2019

Программа отлично компилируется.Я использовал gcc -Wall, и ошибки не отображались.

Но почему-то функция storeFreqDrift не выполняется после остальной части кода.Есть идеи почему?Может быть, какая-то проблема с указателями?в конце кода вводится файл (каждый номер находится в новом ряду).Я хочу вернуть значение массива из функции.Пока все отлично работает, но теперь я застрял.

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

int freqCount;
int calcFreqDrift(const char *file_name, int *result);
int storeFreqDrift(const char *file_name, int tab[freqCount]);

int main() {
    int result = 0;
    freqCount = calcFreqDrift("numbers.txt", &result);
    printf("total number of frequencies is   %d", freqCount);
    int tab[freqCount]; 
    tab[freqCount] = storeFreqDrift("numbers.txt", &tab[freqCount]);
    printf("kolumna nr 3 to %d", tab[3]);
}

int calcFreqDrift(const char *file_name, int *result) {
    FILE *file = fopen("numbers.txt", "r");
    int i = 0;
    int freqCount = 0;  
    if (file == NULL) {
        printf("unable to open file %s", file_name);
    }
    while (fscanf(file, "%d", &i) == 1) {
        freqCount++;
        printf ("%d\n ", i);
        *result += i;
        printf("\n we are at row nr. %d sum of this number and all numbers before is: %d\n", freqCount, *result);
    }
    fclose(file);
    return freqCount; 
}

int storeFreqDrift(const char *file_name, int tab[freqCount]) {
    for (int i = 0; i < freqCount; i++) {
        tab[i] = 5 + tab[i - 1];
    }
    return tab[freqCount];
}

numbers.txt :

-14
+15
+9
+19
+18
+14
+14
-18
+15
+4
-18
-20
-2
+17
+16
-7
-3
+5
+1
-5
-11
-1
-6
-20
+1
+1
+4
+18
+5
-20
-10
+18
+5
-4
-5
-18
+9
+6
+1
-19
+13
+10
-22
-11
-14
-17
-10
-1

Ответы [ 3 ]

0 голосов
/ 24 января 2019

Есть несколько проблем, но ошибка сегмента вызвана этой строкой:

tab[freqCount] = storeFreqDrift("numbers.txt", &tab[freqCount]);

Примечания:

  • &tab[freqCount] - это адрес памяти после вашего массива,C основан на нуле, поэтому массив tab занимает память от &tab[0] до &tab[freqCount - 1]&tab[freqCount] в вызове storeFreqDrift собирается отправиться в город в памяти после массива tab.
  • Как упомянуто в комментариях, tab[i - 1] в вашем цикле for будет отменять ссылкуячейка памяти перед указателем tab, когда i равен нулю.(По иронии судьбы это фактически единственный раз, когда указатель tab в storeFreqDrift фактически указывает на любую часть массива tab из main с учетом приведенного выше примечания.)
  • Потому что int tab[freqCount]; создается в стеке во время выполнения с любым значением, равным freqCount, компилятор ничего не может сделать, чтобы проверить согласованность того, что подается в storeFreqDrift, с объявлением функции.У инструмента статического анализа кода было бы больше информации по этому вопросу (например, http://splint.org/).
  • Опять же, поскольку int tab[freqCount]; создается во время выполнения, нет преимущества иметь сигнатуру функции storeFreqDrift, декларирующую вкладку.Параметр как «массив типа». Он выродится в указатель типа int.
  • После вашего цикла for: return tab[freqCount]; вернет все, что находится в памяти в этом месте. Однако ваш цикл forне будет заполнять это место, скорее он устанавливает значения от tab[0] до tab[freqCount - 1] (где tab - указатель в функции storeFreqDrift, а не массив tab из main).
  • Наконец, обратно в main, вы сохраняете возвращаемое значение в tab[freqCount], который является ячейкой памяти после массива tab.

Когда массив передается в функцию вc, он обрабатывается как указатель, поэтому он будет чище (и не вызовет ошибки), если вы просто вызовите свою функцию как:

value = storeFreqDrift("numbers.txt", tab);
0 голосов
/ 24 января 2019

Измените параметр функции с

int storeFreqDrift(const char *file_name, int tab[freqCount]);

до:

int storeFreqDrift(const char *file_name, int tab[]);
0 голосов
/ 21 января 2019

Из main () в строке 10 вы вызываете calcFreqDrift (), но в этой функции вы закрываете (file) в строке 32, затем из main () в строке 13 вы вызываете storeFreqDrift () с именем файла, который нужно открыть, но storeFreqDrift () не открывает файл и не читает файл. Также в storeFreqDrift () первая строка читается как (int i = 0; i

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...