简体   繁体   中英

Is this a pointer? (And if so, how was it initialized?)

There's a header file, esUtil.h, with a definition for a structure called ESContext, and one of its members is userData. userData is a pointer to void.

The body of a program using it is this, briefly:

#include "esUtil.h"

typedef struct {
 GLuint programObject;
} UserData;

int DoSomething(ESContext *esContext) {
 UserData *userData = esContext->userData;

 ...
}

int main(int argc, char *argv[]) {
 ESContext esContext;
 UserData userData;

 esStart(&esContext);
 esContext.userData = &userData;

 ...
 if(!DoSomething(&esContext))
  return 0;

 ...
}

I'm confused by what "*userData" is in the statement: UserData *userData = esContext->userData;

And if it is a pointer, how it came into being without being declared. Thanks for any explanations.

Yes, it is a pointer. The line

UserData *userData = esContext->userData;

declares a variable called userData with type UserData * (a pointer to UserData ) and initializes it with the value esContext->userData .

Some where in the code the member userData of ESContext might be initialized with the structure UserData and thats why it is assigned to UserData pointer in DoSomething function.

It may be a void pointer but still it might hold the address of UserData object

userData is indeed a pointer. It's declared as a pointer type (the star in the type name is a tip-off), and this code presumably compiles, so it must be a pointer type. And unless any of the code you didn't post deals with userData (in main), yes userData is uninitialized.

You ask "how it came into being without being initialized." Well, in mainstream C/C++ implementations, pointers are really just integers whose size is equal to the word size on the system (32 bits on a 32-bit system, 64 bits on a 64-bit system). If you dereference a pointer, the CPU goes out to the address that the pointer represents, and fetches the associated data. If the data isn't there, your program goes kaboom (on *nix, segfaults) if you're lucky and does weird things if you aren't. In this case, main's userData is declared , so the data actually is there. However, it's not initialized, so the contents of userData could be anything. As long as DoSomething doesn't use the contents of userData , it's OK because it's just manipulating that address. But if it tries to dereference userData , the CPU will go out to memory and pull in garbage, at which point the program could do all kinds of weird things because any bit pattern is possible inside userData , so any calculations on userData could end up with all kinds of different results.

The C/C++ language specs say that using uninitialized values gives undefined behavior, which really is undefined , meaning that the compiler could insert code to erase your hard drive, or send threatening messages to Kernighan and Ritchie, or do anything it likes whenever you use uninitialized values. But the code that real compilers generate just gives garbage bit patterns (usually leftover stack data from previous function calls). So, while using uninitialized values is wrong , it won't kill you.

All of this weirdness about uninitialized values and bad pointers is one of the most visible ways in which C and C++ are unsafe languages. Eric Lippert explains another way in which C and C++ are unsafe here .

它是一个指针,并由以下行初始化:

esContext.userData = &userData;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM