Struct Struggle: Pointers, Variables and De-References

5 posts / 0 new
Last post
cha05e90
cha05e90's picture
Offline
Last seen: 6 years 1 month ago
Joined: 2011-02-07 20:22
Struct Struggle: Pointers, Variables and De-References

While this works in both flavours...

  1. struct TimeVal tv;
  2. ITimer->GetSysTime(&tv);
  3.  
  4. struct TimeVal *tv;
  5. ITimer->GetSysTime(tv);

...this does chrash in the upper, de-referenced ("&ds") variant:

  1. struct DateStamp ds;
  2. IDOS->DateStamp(&ds);
  3.  
  4. struct DateStamp *ds;
  5. IDOS->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...

  1. struct DateStamp *ds = DateStamp( struct DateStamp *ds );
  2.  
  3. // versus
  4.  
  5. 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.

thomas
thomas's picture
Offline
Last seen: 3 months 1 week ago
Joined: 2011-05-16 14:23
struct TimeVal

struct TimeVal tv;
ITimer->GetSysTime(&tv);

This is correct. It allocates memory for a struct TimeVal and calls GetSysTime with a pointer to that memory.

struct TimeVal *tv;
ITimer->GetSysTime(tv);

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.

struct DateStamp ds;
IDOS->DateStamp(&ds);

This is correct. It allocates memory for a struct DateStamp and calls DateStamp() with a pointer to this memory. It should not crash.

struct DateStamp *ds;
IDOS->DateStamp(ds);

This is not correct. Same explanation as above.

This would be correct:

struct DateStamp *ds;
ds = malloc(sizeof(struct DateStamp));
IDOS->DateStamp(ds);

This would be correct, too:

struct DateStamp ds_mem;
struct DateStamp *ds;
ds = &ds_mem;
IDOS->DateStamp(ds);

cha05e90
cha05e90's picture
Offline
Last seen: 6 years 1 month ago
Joined: 2011-02-07 20:22
Thank you very, very much,

Thank you very, very much, Thomas! You rearranged my worldview! :-)

Indeed the culprit was the suspicious snippet:

struct TimeVal *tv;
ITimer->GetSysTime(tv);

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.

X1000|II/G4|440ep|2000/060|2000/040|1000

salass00
salass00's picture
Offline
Last seen: 6 months 1 week ago
Joined: 2011-02-03 11:27
@cha05e90 That is why you

@cha05e90

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.

cha05e90
cha05e90's picture
Offline
Last seen: 6 years 1 month ago
Joined: 2011-02-07 20:22
Funny thing is that I already

Funny thing is that I already compiled with both switches on "-Wall -Werror", but it compiles just nicely without throwing an error or warning.

  1. #include <exec/types.h>
  2. #include <proto/exec.h>
  3. #include <proto/dos.h>
  4. #include <proto/timer.h>
  5.  
  6. int main(void)
  7. {
  8. struct TimeVal *tv;
  9. ITimer->GetSysTime(tv);
  10.  
  11. return (RETURN_OK);
  12. }

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..;-)

X1000|II/G4|440ep|2000/060|2000/040|1000

Log in or register to post comments