0

Is a FILE object created and returned by fopen() a dynamic or static variable or something else?

In the following example,

#include  <stdio.h>
FILE *open_data(void) {
    FILE *fp;
    if ((fp = fopen("datafile", "r")) == NULL)
        return (NULL);
    return (fp);   
}

Is the FILE object created and returned by open_data() an automatic variable? If not, what is its storage duration and linkage?

when a call to open_data() returns, will the FILE object created and returned by open_data() be destroyed?

dbush
  • 205,898
  • 23
  • 218
  • 273
Tim
  • 1
  • 141
  • 372
  • 590
  • It is not destroyed. Only the pointer has automatic storage duration. – Osiris Aug 28 '18 at 22:21
  • It's a `FILE` pointer that must be free'd with `fclose(3)`. – vanza Aug 28 '18 at 22:21
  • It obviously can't be an automatic variable (read about stoarage duration, if you knew, you wouldn't ask). Why do you care about the rest? Sidenote: `return` is not a function, but a statement. The result value should not be parenthtised (ti was not uncommon in the 70ies/early 80ies, but not since C89). – too honest for this site Aug 28 '18 at 22:37
  • You can confirm the allocation by the system associated with `fopen` easily with a memory checking program like `valgrind` (on Linux). If I recall correctly, the system will allocate `~1024 bytes` for the handling of the `FILE*` object returned by `fopen()`. At least on Linux, that memory is still reported as in use unless a corresponding `fclose()` is called on the file stream. (though note with `valgrind > 3.12` the exclusion files no longer account for all system allocated memory, so some allocated memory is likely to be reported as in use, even if you free all you allocate) – David C. Rankin Aug 28 '18 at 22:51
  • Though not directly related to this question but discussion https://stackoverflow.com/questions/8175827/what-happens-if-i-dont-call-fclose-in-a-c-program especially answer by "Adam Rosenfield" give you enough pointer to conclude the type of FILE object return by fopen(). – Vicky Aug 30 '18 at 03:54

4 Answers4

2

The FILE object to which a pointer is returned by fopen() is either allocated from the heap or a static object. In both cases it can be used until the file is closed by fclose(). Returning it from open_data() is perfectly OK.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • 1
    I don't think it's specified by the standard what `FILE` actually is and what the functions return (as long they return a null pointer value on failure).. – too honest for this site Aug 28 '18 at 22:46
  • @toohonestforthissite: Indeed, I did not find a proper quote from the C11 Standard... My answer is rooted in experience and knowledge of actual implementations, and the conclusion seems valid. The Standard does say that the pointer must be considered invalid after a call to `fclose()`. – chqrlie Aug 28 '18 at 23:09
  • "`FILE` which is an object type capable of recording all the information needed to control a stream …" - Afaik in some early implementations it was even a macro, hence the all-uppercase relic. I could easily imagine implementations which use a simple integer handle converted to a pointer, e.g. if the underlying system already handles all stream aspects. – too honest for this site Aug 28 '18 at 23:15
2

open_data, as well as fopen, does not return a FILE object but a pointer to a FILE object. This object was allocated either statically or dynamically by fopen.

Had it been allocated automatically (i.e. as a local variable in fopen) then its address would not be valid.

dbush
  • 205,898
  • 23
  • 218
  • 273
2

The fp is a pointer to FILE object. The fp variable has automatic storage duration in FILE *open_data(void) function block.

The data to which the fp pointer points to, the FILE object, is dependent on fopen() implementation. It may be data with static storage duration on some systems implementations, ie. static FILE obj; FILE *fopen() { return &obj; }, but it may be data with allocated storage duration allocated and deallocated using dynamic memory allocation functions inside fopen() and fclose() calls. For example, look at openbsd, there is from fopen() call to __sfp() which should find free FILE object from list or if not found it should allocate next FILE object.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • Probably should paraphrase the first sentence. I meant: 'The fp a pointer to FILE object. The fp is a pointer with automatic storage duration.' – KamilCuk Aug 28 '18 at 22:41
  • Sidenote: there is nothing like "dynamic storage duration". `malloc` etc. returned objects have allocated storage duration. Other measn than `malloc` could also be used, it's simply not specified by the standard. `FILE` could as well be an integer handle converted to a pointer. – too honest for this site Aug 28 '18 at 22:42
  • Right. There is allocated storage duration in C99. Dynamic is in C++ – KamilCuk Aug 28 '18 at 22:43
  • Not that it would change something about this, but FYI: C standard is C17 (==C11 with corrigenda). – too honest for this site Aug 28 '18 at 23:23
1

The FILE* value returned from fopen() is a pointer to a structure allocated by the system. While the pointer itself will be automatically popped of the stack when the function returns the data it points to will not.

You must call fclose() to free the data allocated by fopen().

codeandkey
  • 69
  • 5
  • 1
    `FILE` is not required to be a `struct`. And there is no stack in C. It's not a good idea in general to mix abstraction levels; better stick to the one in the question, i.e. the abstract machine. – too honest for this site Aug 28 '18 at 22:48