I have a relevant question that highlights my weak understanding of how to work with pointers. I declare a pointer variable called
FILE *MEMORY_CARD = fopen("card.raw", "r")
In my understanding, I have just declared a pointer called MEMORY_CARD that contains the information from a file called card.raw. Ok, now I would like to check if this pointer is NULL.
Do I do it like this:
if (MEMORY_CARD == NULL)
{
exit(1);
}
Or like this:
if (*MEMORY_CARD == NULL)
{
exit(1);
}
It seems like the first case is correct because I have seen it done this way, but based on my current understanding, I thought you would need to do it as per the bottom way. This is because I thought that every time you want to check a value at the address that the pointer is pointing to, you need to use the dereference operator such that *MEMORY_CARD is a reference to the information at that location which is what you want to check for null. I would think that the top way would be invalid as it is asking "Check if what is inside the variable MEMORY_CARD is NULL (Which I never declared. I declared a pointer called *MEMORY_CARD) Variable would be something like int i = 1, where I do not use a pointer.
I get the same confusion by the way when I need to check if what I declare with malloc is Null. Do I reference it with * prefixing the name, or just reference it like I would with a variable. Perhaps I am still confused to the basic definition of pointer vs variable. Hopefully these examples shed a light into a bigger picture concept that I am a bit foggy. I've looked at a few resources myself, but they do not seem to deep dive enough into minutia of this. Hopefully someone can help me clear this up. Thanks in advance!
MEMORY_CARD is the address of your opened file in memory
*MEMORY_CARD is the data of your file structure itself
so you should check MEMORY_CARD
This is because I thought that every time you want to check a value at the address that the pointer is pointing to, you need to use the dereference operator
This is true but does not apply. There is no need to to "check a value at the address", just the address.
The proper check below tests the pointer.
if (MEMORY_CARD == NULL)
{
exit(1);
}
Related
As part of a course I am attending at the moment, we are working in C with self-developed low level libraries, and we are now working in our final project, which is a game.
At a certain point, it seemed relevant to have a struct (serving as a sort of object) that held some important information about the current game status, namely a pointer to a player "object" (can't really call the simulated objects we are using actual objects, can we?).
It would go something like this:
typedef struct {
//Holds relevant information about game current state
state_st currstate;
//Buffer of events to process ('array of events')
//Needs to be pointers because of deallocating memory
event_st ** event_buffer;
//Indicates the size of the event buffer array above
unsigned int n_events_to_process;
//... Other members ...
//Pointer to a player (Pointer to allow allocation and deallocation)
Player * player;
//Flag that indicates if a player has been created
bool player_created;
} Game_Info;
The problem is the following:
If we are to stick to the design philosophy that is used in most of this course, we are to "abstract" these "objects" using functions like Game_Info * create_game_info() and destroy_game_info(Game_Info * gi_ptr) to act as constructors and destructors for these "objects" (also, "member functions" would be something like update_game_state(Game_Info * gi_ptr), acting like C++ by passing the normally implicit this as the first argument).
Therefore, as a way of detecting if the player object inside a Game_Info "instance" had already been deleted I am comparing the player pointer to NULL, since in all of the "destructors", after deallocating the memory I set the passed pointer to NULL, to show that the object was successfully deallocated.
This obviously causes a problem (which I did not detect at first, and thus the player_created bool flag that fixed it while I still was getting a grasp on what was happening) which is that because the pointer is passed by copy and not by reference, it is not set to NULL after the call to the "object" "destructor", and thus comparing it to NULL is not a reliable way to know if the pointer was deallocated.
I am writing this, then, to ask for input on what would be the best way to overcome this problem:
A flag to indicate if an "object" is "instanced" or not - using the flag instead of ptr == NULL in comparisons to assert if the "object" is "instanced" - the solution I am currently using
Passing a pointer to the pointer (calling the functions with &player instead of only player) - would enable setting to NULL
Setting the pointer to NULL one "level" above, after calling the "destructor"
Any other solution, since I am not very experienced in C and am probably overlooking an easier way to solve this problem.
Thank you for reading and for any advice you might be able to provide!
I am writing this, then, to ask for input on what would be the best way to overcome this problem: …
What would be the best way is primarily opinion-based, but of the ways you listed the worst is the first, where one has to keep two variables (pointer and flag) synchronized.
Any other solution…
Another solution would be using a macro, e. g.:
#define destroy_player(p) do { /* whatever cleanup needed */; free(p), p = NULL; } while (0)
…
destroy_player(gi_ptr->player);
void table_no_op()
{
// this is for function table elements that do nothing,
// fills space between states, use less of them
return;
}
I am currently using this to define a "zero" in a function pointer table, where the input index is supposed to do nothing. Is it okay or something glaringly wrong?
While there's nothing wrong with the no-op per se (in general, this is called Null Object Pattern), I would be worried about the function declaration - i.e. does every function in the table take 0 arguments and return void?
A counterexample would be OpenGL where you often retrieve a pointer to function and cast it to the desired type yourself - but casting a void->void pointer to something else, e.g. (int, int)->int would be undefined behavior and likely cause crash (or uninitialized return value, or else).
So, if the functions in the table are homogeneous - go for it. If not - better do something else.
EDIT: You can only do 2 things with a function pointer - cast it to a different function pointer; and call, but only with the original type.
See http://blog.frama-c.com/index.php?post/2013/08/24/Function-pointers-in-C for details. Raymond Chen has another example here - http://blogs.msdn.com/b/oldnewthing/archive/2011/05/06/10161590.aspx
EDIT2: However, you may make a number of no_ops (noop_IntInt_Int, noop_IntDouble_Double and so on... then if you match the types every time, that might work)
I'm changing some codes in a database library. The way it works I send a void pointer, to get the size of it I call a query and using the query I calculate the size of the structure. Now the problem is I receive the struct as params but the function fails before/in the middle of the first fetch. After that I need to clear the structure, but I dont even have the size.
I know the best way is send the size of the structure as a param, but I have thousands and thousands programs already compiled, the library is from 1996, so I need to find a way to calculate the structure size even if the type is void.
One idea I had was to calculate the position of the next element that is not in the structure
0x000010 0x000042
[int|char[30]|int|int][int]
So the size is 32, because the 0x00042-0x000010 is 32.
Is there a way to know when I got out of the structure.
the prototype of the function is
int getData(char* fields, void* myStruct)
I need to find out the structure size.
Sorry if I missed some information, the code is HUGE and unfortunately I cannot post it here.
No, in general there's no way, given a void *, to figure out what you're after. The only thing you can do is compare it against NULL, which of course doesn't help here.
Note that there's nothing in the void * that even says it points at a struct, it could just as well be pointing into the middle of an array.
If you have some global means of recording the pointers before they're passed to getData(), you might be able to implement a look-up function that simply compares the pointer value against those previously recorded, but that's just using the pointer value as a key.
I've got a structure which holds names and ages.
I've made a linked-list of these structures, using this as a pointer:
aNode *rootA;
in my main.
Now i send **rootA to a function like so
addElement(5,"Drew",&rootA);
Because i need to pass rootA by reference so that I can edit it in other functions (in my actual program i have two roots, so return will not work)
The problem is, in my program, i can't say access the structure members.
*rootA->age = 4;
for example doesnt work.
Hopefully you guys can help me out.
Thanks!
It's hard to tell from your question but it looks like the type of rootA in the last sample is aNode**. If so the reason why it's failing is that -> has higher precedence than *. You need to use a paren to correct this problem
(*rootA)->age = 4;
See full C Operator Precedence Table.
If the type of rootA is instead aNode*. Then you don't need to dereference in addition to using ->. Instead just use -> directly
rootA->age = 4;
I suspect you need to pass a pointer to the rootA variable, and not dereference it twice.
addElement(5,"Drew",&rootA);
That's an issue I still don't understand.
Sometimes I have to write:
NSString* myVariable;
myVariable = #"Hey!";
Then, for example I define a Structure "DemoStruct" and get an Variable that uses it. Lets say I have a Structure that has x and y vars from type double.
I want to pass this var to a method which then manipulates my var, and I want that this manipulation has effect on the context from which I passed the var to that method. So I need a pointer, right.
I pass it to the method like that:
[someObject someMethod:&myVarThatUsesTheStruct]
that method now looks like that:
- (void)someMethod:(DemoStruct*)myVar {
(*myVar).x += 10;
}
Before the call, the component x of the struct was lets say 1000. Now, 10 is added and it is 1010 after the method call.
But I really really hardly dont get it why I have to use the Asterisk * for myVar in the Method, since I say already in the Method Header that myVar is a POINTER to a DemoStruct. I just pass with &myVarThatUsesTheStruct the memory address.
Can someone explain why this is like it is?
As you say, myVar is a pointer. As such, myVar.x is not correct: it would by a field of a pointer, which has no sense in C/Objective-C.
If you want to access to the variable pointed to by a pointer, you have to add the asterisk: myVar is a pointer, *myVar is the variable pointed to by myVar.
Moreover, in your case, you can use a special construct of C by writing myVar->x, which is strictly equivalent to (*myVar).x.
All of this is standard C, not specific to Objective-C.
About your first example, you don't have to put an asterisk because you change the value of the pointer, not the value of the variable: myVariable is a pointer to an object which at declaration time is assigned the nil value. The next instruction (myVariable = #"Hey!") is an assignment of pointer values: #"Hey!" is a pointer to a NSString object. The value of this pointer (not the value of the pointed constant) is assigned to myVariable, which then points to the object #"Hey!".
Yes, this is diffucult to follow at first time...
* is the dereference operator. All that *myVar means is "Get me the thing that the pointer myVar points to". You need this distinction because you need to tell the computer that you want to change the thing that myVar points to, not myVar itself.
taken from the learning objective c link via the developers portal for iphone devs:
Objective-C supports both strong and weak typing for variables
containing objects. Strongly typed variables include the class name in
the variable type declaration. Weakly typed variables use the type id
for the object instead. Weakly typed variables are used frequently for
things such as collection classes, where the exact type of the objects
in a collection may be unknown. If you are used to using strongly
typed languages, you might think that the use of weakly typed
variables would cause problems, but they actually provide tremendous
flexibility and allow for much greater dynamism in Objective-C
programs.
The following example shows strongly and weakly typed variable
declarations:
MyClass *myObject1; // Strong typing
id myObject2; // Weak typing
Notice the * in the first declaration. In Objective-C, object
references are pointers. If this doesn’t make complete sense to you,
don’t worry—you don’t have to be an expert with pointers to be able to
start programming with Objective-C. You just have to remember to put
the * in front of the variable names for strongly-typed object
declarations. The id type implies a pointer.