-2

I keep getting a seg fault if and only if I attempt to close a file:

   FILE *outFilePtr = fopen(*(argv + 2), "w"); //open file, yes i'm sure it opens


   fclose(outFilePtr); //sometime later in the program.

The program runs from start to finish without the flcose(). Any suggestions?

The error on gdb redirects here: Assume it is a function with all variables declared. Also gdb blames strtol which I'm not even using.

 int t;
     char line[50];

          for (t = 0; t < lines; t++){
              fgets(line, 50, filePtr);
             strcpy(*string[t], strtok(line, " "));
              *(num1 + t) = atoi(strtok(NULL, " "));
              *(num2 + t) = atoi(strtok(NULL, " "));
           }

Memory Allocation Function

 void dynamicArray(int** num1, int** num2, char*** str, int size)
 { 
     int i = 0;

*(num1) = (int*)malloc(sizeof(int) * size);
*(num2) = (int*)malloc(sizeof(int) * size);

*(str) = (char**)malloc(sizeof(char*) * size);

for( i = 0; i < size; i++){
    *(*(str) + i) = (char*)malloc(sizeof(char) *size);
}

return;
 }
SystemFun
  • 1,062
  • 4
  • 11
  • 21

3 Answers3

1

Just to be sure, check that outFilePtr is not null:

if (outFilePtr) {fclose(outFilePtr); outFilePtr = NULL;}

I always do it when closing the file and I also put the pointer to NULL to avoid trying to close the same file twice (that may cause trouble as well).

But most likely the cause is some memory leak or undefined behaviour that messes things around and segfault is just triggered by the fclose().

Remo.D
  • 16,122
  • 6
  • 43
  • 74
  • So why would the fclose() trigger it. The error code points to an error with the atoi, but the arrays all fill correctly.. I don't understand. – SystemFun Feb 18 '13 at 17:13
  • on `fclose()` the standard library releases resources to the OS. I can imagine that if something is messed up at that point you may end up writing on read-only memory or triggering some other exception (div by zero seems unlikely to me but still possible). – Remo.D Feb 18 '13 at 17:19
  • So most likely, I have some memory somewhere that is not where it should be, and the program doesn't realize this until I try and close this file? – SystemFun Feb 18 '13 at 17:20
  • Exactly so. Valgrind or some `assert()` around might help you find the right spot. – Remo.D Feb 18 '13 at 17:26
1

My guess is that the value of outFilePtr is not being preserved when you get to fclose().

Your code snippet is too short, and misses out too much other stuff that could be important... What is strings and num2; how big are they allocated; etc...

also, the first store to *(num2 + t) gets overwritten by the second *(num2 + t).

also, also, have a look at ARRAYS.... num2[t] is much easier to read than *(num2+t) and does the same job.

Anonymouse
  • 935
  • 9
  • 20
  • The overwrite part is an not applicable that was an error in transferring code. I can't give the whole program its quite long.. How would it not be preserved? And why would it direct here? – SystemFun Feb 18 '13 at 17:16
  • The easiest way not to be preserved is because it's been overwritten - hence my query about all the allocations. Try adding `printf ("%X\n", (unsigned)outFilePtr);` after fopen and before fclose - make sure the value is same. Another thought - you're not fclose'ing more than once are you? – Anonymouse Feb 18 '13 at 18:00
1

Except for your horrible array access syntax. You forgot to duplicate your input string line. The strtok always point to the same buffer that change on every line.

 int t;
 char line[50];

      for (t = 0; t < lines; t++){
          fgets(line, 50, filePtr);
          strings[t] = strdup(strtok(line, " ")));
          num1[t]    = atoi(strtok(NULL, " "));
          num2[t]    = atoi(strtok(NULL, " "));
       }

In you allocation code you also allocate only 5 bytes instead of 50. If you really only allocated 5 bytes, then you clobbert the heap and this manifests often by crashing fclose.

void dynamicArray(int** num1, int** num2, char*** str, int size)
{ 
int i = 0;

*num1 = malloc(sizeof(int) * size);
*num2 = malloc(sizeof(int) * size);

*str = malloc(sizeof(char*) * size);

for( i = 0; i < size; i++)
  (*str)[i] = malloc(50);      /* sizeof (char) is by definition 1 */

return;
}
Patrick Schlüter
  • 11,394
  • 1
  • 43
  • 48