0

The program compiles fine. I used gcc -Wall, and no errors were shown.

But somehow the function storeFreqDrift is not executed after the rest of the code. Any ideas why? Maybe some problem with pointers? at end of the code there is the file input (each number is in a new row). I want to return the array value from the function. Everything works fine so far, but now I'm stuck.

#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
9
  • What happens in tab[i]=5+tab[i-1] when i==0? Commented Jan 20, 2019 at 21:15
  • 1
    it worst than 'just that' because storeFreqDrift receive &tab[freqCount] as second argument being in theory tab ! Commented Jan 20, 2019 at 21:23
  • @Alain Merigot , it is just example to assign any value to tab to see if it is going to work Commented Jan 20, 2019 at 21:25
  • I don't entirely follow the purpose of using globals and variable references here. Why not simply make each function an encapsulated black box that takes input and returns output without relying on external state? This will likely resolve your woes and make it easy to follow your program logic. Commented Jan 20, 2019 at 21:26
  • 2
    @kenshin yes, this is why &tab[freqCount] is just after the last element of tab Commented Jan 20, 2019 at 21:29

3 Answers 3

1

From main() on line 10 you call calcFreqDrift() but in that function you close(file) on line 32 , then from main() on line 13 you call storeFreqDrift() with the name of file to open, but storeFreqDrift() does not open the file and does not read the file. Also in storeFreqDrift() the first line reads for(int i=0; i

Sign up to request clarification or add additional context in comments.

1 Comment

problem with editing my answer... in the body in storeFreqDrift you access tab[i-1] so you are before the first position (zero) in your array
1

There are a few issues, but the seg fault is caused by this line:

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

Notes:

  • &tab[freqCount] is the address of memory after your array. C is zero based, so the tab array occupies memory from &tab[0] to &tab[freqCount - 1]. With &tab[freqCount] in the call, storeFreqDrift is about to go to town on the memory after the tab array.
  • As mentioned in the comments, tab[i - 1] in your for loop will de-reference the memory location before the pointer tab when i is zero. (Ironically, this is actually the only time that the pointer, tab, in storeFreqDrift actually points to any part of the array tab from main given the above note.)
  • Because int tab[freqCount]; is created on the stack at runtime with whatever the value of freqCount is, there is nothing the compiler can do help check the consistency of what is being fed into storeFreqDrift against the function declaration. A static code analysis tool would have more to say on the matter (e.g. http://splint.org/).
  • Again, as int tab[freqCount]; is created at runtime, there is no advantage to having the storeFreqDrift function signature declaring the tab parameter as "array of type". It will degenerate to an int pointer.
  • After your for loop: return tab[freqCount]; will return whatever is in the memory at that location. However, your for loop will not have populated this location, rather it sets values from tab[0] to tab[freqCount - 1] (where tab is the pointer in the storeFreqDrift function and not the array tab from main).
  • Finally, back in main, you store the return value into tab[freqCount], which is the memory location after the tab array.

When an array is passed into a function in c, it is treated as a pointer. So it would be cleaner (and wouldn't seg fault) if you just called your function as:

value = storeFreqDrift("numbers.txt", tab);

Comments

0

Change the function parameter from

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

to:

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

Comments