1

I'm working on a dynamic array problem right now and have created a destructor for it. The code compiles just fine, but because I haven't been provided with a test file, I'm not actually sure if the destructor is fully functional. Would anyone be able to tell me if I'm on the right track? I've included my header in full, and .cpp with some irrelevant functions removed for the sake of readability. Destructor designated with // This is the function in question // in .cpp. Any help appreciated!

dynamic_array.h

using namespace std;

class Dynamic_array {
public:
    Dynamic_array();
    Dynamic_array(Dynamic_array &);
    Dynamic_array &operator=(Dynamic_array &);
    ~Dynamic_array();

    void print_state(void);
    int get_size(void);

    int& operator[](int);

    void insert(int, int);
    void insert(Dynamic_array &, int);

    void remove(int);
    void remove(int, int);

    class Subscript_range_exception {
    };
private:
    enum {
        BLOCK_SIZE = 5,
    };

    class Block {
    public:
        int size;
        int a[BLOCK_SIZE];
        Block* next_p;
    };

    class Block_position {
    public:
        Block* block_p;
        Block* pre_block_p;
        int i;
    };

    Block_position find_block(int i);
    void insert_blocks(Block *, Block *);
    void remove_blocks(Block *, Block *, Block *);
    Block * copy_blocks(Block *);
    void delete_blocks(Block *);

    int size;
    Block* head_p;
};

dynamic_array.cpp

#include <iostream>                                     
#include <string.h>                                     
#include "dynamic_array.h"                                  

using namespace std;                                        

// ********** public functions **********                           

Dynamic_array::Dynamic_array() {                                
    head_p = NULL;                                      
    size = 0;                                       
}                                               

Dynamic_array::Dynamic_array(Dynamic_array & d) {                       
    size = d.size;      
    head_p = copy_blocks(d.head_p); 
}                                               


Dynamic_array &Dynamic_array::operator=(Dynamic_array & d) {                    
    if (this != &d){
        this->head_p = copy_blocks(d.head_p);   
        this->size = d.size;
    }

    return *this;                                           
}                                               

Dynamic_array::~Dynamic_array() {   // This is the function in question //                      
 if(head_p != NULL){
        while (1) {                                                                 
        Block * p = head_p->next_p;                         
        delete head_p;                                                                      
        // advance                                  
        if (p == NULL) {                                
            break;                                  
        } else {                                    
            head_p = p;                             
        }                                       
    }
 }
}                                                                                                                                                                                           

// ********** private functions **********                                                                                                                          

// purpose                                          
//  create a new linked list which is a copy of the list pointed to p           
//  return a pointer to the head of the new linked list                 
// preconditions                                        
//  p is the head of a possibly empty linked list of blocks                 
Dynamic_array::Block * Dynamic_array::copy_blocks(Block * p) {                  
    Block * new_head_p = NULL;                              
    Block * new_p;                                      
    while (p != NULL) {                                 
        // allocate and link in new block                       
        if (new_head_p == NULL) {                           
            new_p = new Block;                          
            new_head_p = new_p;                         
        } else {                                    
            new_p->next_p = new Block;                      
            new_p = new_p->next_p;                          
        }                                       

        // copy the elements                                
        new_p->size = p->size;                              
        for (int i = 0; i < p->size; i++) {                     
            new_p->a[i] = p->a[i];                          
        }                                       

        // advance                                  
        p = p->next_p;                                  
    }                                           

    // terminate new list                                   
    if (new_head_p != NULL) {                               
        new_p->next_p = NULL;                               
    }                                           

    return new_head_p;                                  
}
Mock
  • 359
  • 1
  • 3
  • 11
  • Good job on covering the Rule of Three. Can I talk you into the Rule of Five as well? Given the nature of what you've written, a move constructor and move assignment is appropriate. – user4581301 Feb 24 '17 at 04:31
  • Yes, I do know about the Rule of 5, but this assignment involves being given specific functions that we need to create. In this case, Rule of 3 is sufficient, and the program will stand up to all test cases without the Rule of 5. – Mock Feb 24 '17 at 04:33
  • Done deal then. Not getting paid, don't over provide. – user4581301 Feb 24 '17 at 04:38

1 Answers1

3

You can simplify your destructor function this way.

Dynamic_array::~Dynamic_array() {   // This is the function in question //
    while (head_p != NULL) {
        Block *p = head_p;
        head_p = head_p->next_p;
        delete p;
    }                      
}

Side note:

Copy Constructor and assignment operator should have const arguments

Dynamic_array::Dynamic_array(const Dynamic_array & d) {                       
    size = d.size;      
    head_p = copy_blocks(d.head_p); 
}                                               


Dynamic_array &Dynamic_array::operator=(const Dynamic_array & d) {                    
    if (this != &d){
        this->head_p = copy_blocks(d.head_p);   
        this->size = d.size;
    }

    return *this;                                           
}                                               
Gunner Stone
  • 997
  • 8
  • 26
Rishi
  • 1,387
  • 10
  • 14
  • Okay, this makes sense, thank you. I've accepted your answer. – Mock Feb 24 '17 at 04:31
  • Thank you. You can post your code review questions here : http://codereview.stackexchange.com/ – Rishi Feb 24 '17 at 04:34
  • Totally off topic: @Mock for another way to implement the assignment operator take a look at [What is the copy-and-swap idiom?](http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom) – user4581301 Feb 24 '17 at 04:34
  • @user4581301 thank you, this is useful. Rishi, thank you, I didn't know about this section. – Mock Feb 24 '17 at 04:37