c++ - Questions about the logic and scope of a destructor that frees a linked list from memory -


i have class called stopwatch i'm working on (so please ignore of incompleteness below). interface supposed abstraction of stopwatch in real life. right i'm trying write destructor, free memory linked list represents laps.

class stopwatch {     typedef enum {unstarted, running, paused, finished} state;     typedef struct     {         unsigned hours;         unsigned minutes;         unsigned seconds;     } time;     typedef struct     {        unsigned n; // lap number        time t; // lap time        lap* next_ptr;     } lap;      public:      stopwatch();     ~stopwatch();     void right_button(); // corresponds start/stop/pause     void left_button();  // corresponds lap/reset      private:      state cur_state;     lap* first_ptr;  }  stopwatch::stopwatch() {     cur_state = unstarted;     first_ptr = null; }  stopwatch::~stopwatch() {     // destroy laps     (lap* thisptr = first_ptr; thisptr != null;)     {         lap* tempptr = thisptr;          thisptr = thisptr.next_ptr;         free (tempptr);      }     cur_state = finished; } 

i have not tried compile yet, have few questions before proceed.

(1) logic freeing linked list correct? procedure used is

(i) set thisptr equal pointer first lap.

(ii) while thisptr isn't null, store copy of thisptr, increment thisptr, free memory copy points to

which seems correct, again pointers still tricky me.

(2) supposed set pointer equal null after using free on it? in code samples i've seen far, when writer wanted rid of variable used free on it. reading guy's instructions http://www.cprogramming.com/tutorial/c/lesson6.html , says set equal null afterwards. i've thought tutorials good.

(3) need use namespace operator when i'm referring lap* in destructor? i.e., need write stopwatch::lap* instead of lap* ??? did declare lap structure in correct place inside class?

setting pointer null after releasing not necessary. can recommended if there use after free() code (should...) crash , easier debug. in c++ should not need it, because should raii , never have raw pointer ownership.

note in c++ use new , delete, not malloc , free.

you loop not idiomatic, looks more while loop more readable way:

lap* thisptr = first_ptr; while(thisptr) {     lap* tempptr = thisptr;      thisptr = thisptr.next_ptr;     free (tempptr);  } 

the logic seem ok. if not homework project, should change few things:

1) use standard containers. if can use vector, use it. if code not fit vector, rethink use vector ;-) don't need destructor if change code way:

class stopwatch {     ...     typedef struct     {        unsigned n; // lap number        time t; // lap time     } lap;      ...      private:      ...     std::list<lap> laps; // use vector?  } 

note, in c++ declare struct way:

    struct lap     {        unsigned n; // lap number        time t; // lap time     }; 

and can refer using lap inside stopwatch class.

2) c++11 provides date/time utility:

class stopwatch {     ...     typedef std::chrono::system_clock::time_point time;     ... } 

3) practice use initializer list in constructor:

stopwatch::stopwatch()   : cur_state(unstarted) { } 

you don't need constructor simple cases in c++11:

class stopwatch {     ...     private:      state cur_state = unstarted;     ... } 

note changing state finished in destructor pretty useless, object is... destroyed.


Comments

Popular posts from this blog

java - Intellij Synchronizing output directories .. -

git - Initial Commit: "fatal: could not create leading directories of ..." -