While this works in both flavours...
- struct TimeVal tv;
- struct TimeVal *tv;
...this does chrash in the upper, de-referenced ("&ds") variant:
- struct DateStamp ds;
- struct DateStamp *ds;
I must admit that I'm still sometimes lost in regards of buildung structs and passing pointers/addresses to OS API functions.
There must be some unknown mystery that I were not able to decypher yet. I already saw that the synopsis for the used functions here differ...
- struct DateStamp *ds = DateStamp( struct DateStamp *ds );
- // versus
- void GetSysTime( struct TimeVal * );
...but I still did not understand what in these definitions tell me how and why I have to feed the structures (like TimeEval or DateStamp) to them.
This is correct. It allocates memory for a struct TimeVal and calls GetSysTime with a pointer to that memory.
This is not correct. It allocates memory only for a pointer but does let it point to a memory area. When you call GetSysTime with this uninitialized pointer, the result is written to where the pointer points to. This could be anywhere. Another programs' memory, unallocated memory, an address where no memory is at all, the I/O registers of an expansion card, anything. Depending on where the pointer points to, it might crash or might work (by accident) or might let another program crash, let your harddrive crash, do anything strange.
This is correct. It allocates memory for a struct DateStamp and calls DateStamp() with a pointer to this memory. It should not crash.
This is not correct. Same explanation as above.
This would be correct:
This would be correct, too:
Thank you very, very much, Thomas! You rearranged my worldview! :-)
Indeed the culprit was the suspicious snippet:
I had *not* commented it out in my test source - so it, as you assumed right, worked only by pure chance, but thrashed memory. Everything else in that litte C program after this part behaved strangely - even the parts that *should* have worked correctly. Thanks for your explanations.
That is why you should enable warnings with -Wall when compiling with gcc/g++. If you had done that it would have warned you about using the value of an uninitialized variable.
Another option which is useful in conjunction with -Wall is -Werror which makes gcc/g++ treat all warnings as errors (i.e. they make the compile fail).
Compiler warnings can be very useful for finding bugs in C/C++ code so they shouldn't just be ignored.
Funny thing is that I already compiled with both switches on "-Wall -Werror", but it compiles just nicely without throwing an error or warning.
Nevertheless your suggestion is absolutley correct - with this switches on gcc already found a lot of my newbie errors while it tried to compile that stuff..;-)