开发者

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

  1. cfPtr = fopen( "file.dat", "w" ) //Note that, fopen returns FILE* that gets //assigned to cfPtr

  2. if( cfPtr == NULL)


Maybe you can test some of its members? Maybe _ptr or _tmpfname, for instance?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜