How can a FILE* (pointer to a struct) be tested (if == NULL)?
I was playing around with C, anyways I was thinking how can file pointer (which points to a struct type), be tested if NULL as for instant:
FILE *cfPtr;
if ( ( cfPtr = fopen( "file.dat", "w" ) ) == NULL )
I tried to do that myself, but an error occurs.
struct foo{
int x;
};
struct foo bar = {0};
if (bar == NULL)
puts("Yay\n");
else
puts("Nay");
error C2088: '==' : illegal for struct
Here's the FILE deceleration in the stdio.h file:
struct _iobuf {
char *_ptr;
int _cnt;
cha开发者_JAVA百科r *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;
It should be a pointer to a struct:
struct foo* bar = ...
if (bar == NULL)
puts("Yay\n");
else
puts("Nay");
Pointers to structs can indeed be tested for nullness, just as pointers to primitive types.
You must take care of the distinction between a value and a pointer. Pointers hold the address of a value - usually (although not always) a value allocated using malloc().
In your example
struct foo bar = {0};
if (bar == NULL)
puts("Yay\n");
else
puts("Nay");
bar is allocated on the stack - it is not a pointer, so you cannot compare it with NULL (which is a value - in fact 0 on every implementation I have used).
You probably want something more like
struct foo* bar = malloc(sizeof(struct foo));
if (bar == NULL)
puts("Yay\n");
else
puts("Nay");
bar->x = 0;
Notice that you cannot put a value into bar until you have checked whether it is not NULL. If you forget this you will get a NULL pointer dereference error.
You are trying to point to something that contains a null. That's not the same as a pointer with the value 0, which points to the address null of its address space.
The manpage says: "Upon successful completion fopen(), fdopen() and freopen() return a FILE pointer. Otherwise, NULL is returned and the global variable errno is set to indicate the error."
In the case that it returns 0 there is no valid FILE struct to point to.
FILE *p
is a pointer and it is meaningful to compare it with NULL value. On the other hand,
struct foo bar = {0};
if (bar == NULL)
makes no sense (not the one you want at least), nor it does a thing like &bar == NULL
; the latter would work, but would be always false, since struct foo bar = {0}
's memory exists for sure. So indeed there's no way how there can be a failure for struct foo bar;
: the memory is "allocated" correctly or the program fails some other way.
struct foo *bar;
bar = malloc(sizeof(struct foo));
if ( bar == NULL ) // ...
says that bar is a pointer (and we try to malloc the needed memory to hold struct foo), and so bar == NULL
is ok.
You can say somethig like FILE p
which is different from FILE *p
(and not suggested, FILE *
must be considered an "opaque" pointer you shouldn't be interested to, since it may be different in different implementation)
Add after reading a comment of the asker
FILE *cfPtr;
if ( ( cfPtr = fopen( "file.dat", "w" ) ) == NULL )
This works since first the left inner () is evaluated, and so the cfPtr is assigned to the result of fopen, like if it were an alone statemente cfPtr = fopen(...)
. After that, this same result (the value of cfPtr) is compared to NULL. fopen
returns a FILE *
of course, and a pointer can be compared to NULL.
if your Q is how can this code work:
if ( ( cfPtr = fopen( "file.dat", "w" ) ) == NULL ) ?
==> its equivalent to
cfPtr = fopen( "file.dat", "w" )
//Note that, fopen returnsFILE*
that gets //assigned to cfPtrif( cfPtr == NULL)
Maybe you can test some of its members? Maybe _ptr or _tmpfname, for instance?
精彩评论