Deleting an 2d array created with new in a class

Is this the proper way to delete matrix?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

class map_item{
    public:
        map_item(micro_behavior *add, std::string k) : address(add), key(k){ 
            for (int i=0; i< 2 ; i++) {
                matrix[i] = new std::string[2];
            }
            
            for (int n=0; n<2; n++)
                for (int m=0; m<2; m++) {
                   matrix[n][m]="I";    
            }
            
            
        };
        ~map_item(){ delete matrix;}; //Deleting matrix here
        void print(){
            std::cout << "Key : " << key << std::endl; 
            for (int n=0; n<2; n++)
                for (int m=0; m<2; m++) {
                   std::cout << n << "," << m << " " << matrix[n][m] << std::endl;    
            }
            
        }
        std::string key;
        micro_behavior *address;
        std::string **matrix=new std::string*[2];
        
    };


Thanks
Chris
closed account (48T7M4Gy)
A very comprehensive solution plus other stuff. Worth the effort.

http://stackoverflow.com/questions/936687/how-do-i-declare-a-2d-array-in-c-using-new
If the size of the matrix is a constant known at compile time:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class map_item{

    public:

        map_item(micro_behavior *add, std::string k) : key(k), address(add) {

            // range-based for: http://www.stroustrup.com/C++11FAQ.html#for
            for( auto& row : matrix )
                for( std::string& item : row ) item = "I" ;
        }

        void print() const {

            std::cout << "Key : " << key << '\n' ;

            for (int row=0; row<N; ++row)
                for (int col=0; col<N; ++col )
                   std::cout << row << ',' << col << "  " << matrix[row][col] << '\n' ;
        }

        // ...

        std::string key;
        micro_behavior *address;

        static constexpr int N = 2 ;
        std::string matrix[N][N] ; // or use std::array
};


If not, strongly favour std::vector over dynamically allocated C-style arrays:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class map_item{

    public:
        map_item(micro_behavior *add, std::string k, std::size_t n )
            : key(k), address(add), matrix( n, std::vector<std::string>( n, "I" ) ) {}

        void print() const {

            std::cout << "Key : " << key << '\n' ;

            for (std::size_t row=0; row < matrix.size(); ++row)
                for (std::size_t col=0; col< matrix[row].size(); ++col )
                   std::cout << row << ',' << col << "  " << matrix[row][col] << '\n' ;
        }

        // ...

        std::string key;
        micro_behavior *address;

        // https://cal-linux.com/tutorials//vectors.html
        std::vector< std::vector<std::string> > matrix ;
};
I put in the changes using the first option since the size of the matrix is known but I seem to be running into some issues with make pair. Sorry as it is pretty clunky. I just started studying CPP 6 months ago. Its probably full of "bad practice" and outdated techniques.. Error is "main.cpp:152:100: error: no matching function for call to ‘std::map<std::basic_string<char>, std::basic_string<char> [2][2]>::insert(std::pair<std::basic_string<char>, std::basic_string<char> (*)[2]>)’"

Thanks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#include <cstdlib>
#include <string>
#include <iostream>
#include <map>
#include <vector>
class micro_behavior;

   class map_item{
    public:
        map_item(micro_behavior *add, std::string k) : address(add), key(k){ 
            /*for (int i=0; i< 2 ; i++) {
                matrix[i] = new std::string[2];
            }
            
            
            for (int n=0; n<2; n++)
                for (int m=0; m<2; m++) {
                   matrix[n][m]="I";    
            }
            */
            for( auto& row : matrix )
                for( std::string& item : row ) item = "I" ;
            
        };
        ~map_item(){ };
        void print(){
            std::cout << "Key : " << key << std::endl; 
            
            /*for (int n=0; n<2; n++)
                for (int m=0; m<2; m++) {
                   std::cout << n << "," << m << " " << matrix[n][m] << std::endl;    
            }*/
            for (int row=0; row<N; ++row)
                for (int col=0; col<N; ++col )
                   std::cout << row << ',' << col << "  " << matrix[row][col] << '\n' ;
            
        }
        std::string key;
        micro_behavior *address;
        //std::string **matrix=new std::string*[2];
        static constexpr int N = 2 ;
        std::string matrix[N][N] ; // or use std::arr
        
    };
    
    
    enum run_type {
        F, //bool false=0
        S
    };
    
    enum result_type {
        f, //bool false=0
        s
    };
    
    class micro_behavior {
    public:
        micro_behavior(std::string i) : id(i) {};
        ~micro_behavior() {
            for (std::vector<map_item*>::iterator f_it = map_items.begin(); f_it != map_items.end(); ++f_it) {
                delete (*f_it);
            }
        }
        
        map_item * operator()(run_type a, result_type b){
          map_item * temp=new map_item(this, this->id);
          temp->matrix[a][b]="O";
          map_items.push_back(temp);
          return temp;
        }
        
        void print_map() {
            for (std::map<std::string, std::string[2][2]>::iterator it = mapper.begin(); it != mapper.end(); ++it) {
                std::cout << "Referrer : " << it->first << std::endl;
                for (int n=0; n<2; n++) {
                  for (int m=0; m<2; m++) {
                     std::cout << n << "," << m << " " << it->second[n][m] << std::endl;    
                  } 
                }
            }
        }
        
        std::vector<map_item*> map_list;
        std::string id;
        //std::map<std::string, std::string**> mapper;
        std::map<std::string, std::string[2][2]> mapper;
        std::vector<map_item*> map_items;
    };
        
    
    class Macro_behavior {
    public:
        Macro_behavior(std::string i) : id(i) {
          M=new micro_behavior("M");
          T=new micro_behavior("T");
          V=new micro_behavior("V");
          X=new micro_behavior("X");
          
          this->program({(*M)(S,s),(*T)(S,s),(*V)(S,s),(*X)(S,s)});  //why cant I use -> here?
          
        }
        
        
        
    
    void program(std::initializer_list<map_item*> a_args){
        std::vector< map_item*> items;
        std::map< std::string, micro_behavior * > key_address;
        for (auto i: a_args) {
            
            items.push_back(i);
            key_address.insert(std::make_pair(i->key, i->address));
        }
        
        std::cout << "Before " << std::endl;
        
        for (std::vector<map_item*>::iterator f_it = items.begin(); f_it != items.end(); ++f_it) {
            (*f_it)->print();
            std::cout << "-----------------------------------------" << std::endl;
        }
        
        for (std::vector<map_item*>::reverse_iterator f_it = items.rbegin(); f_it != items.rend(); ++f_it) {
            
            if (f_it == items.rbegin()) { //end
                std::string oldkey=(*f_it)->key;
                  std::vector<map_item*>::reverse_iterator next=f_it;
                  ++next;
                  for (int n=0; n<2; n++) {
                    for (int m=0; m<2; m++) {
                       if ((*f_it)->matrix[n][m] == "O") {
                           (*f_it)->matrix[n][m] = "I";
                       }
                    } 
                  }
                  
                  for (std::map<std::string, micro_behavior*>::iterator it = key_address.begin(); it != key_address.end(); ++it) {
                      if (it->first==oldkey) {
                          (*it->second).mapper.insert(std::make_pair((*next)->key, (*f_it)->matrix)); //ERROR here
                      }
                  }
             
            }  else if (f_it == (items.rend()-1) ) { //start
                std::string oldkey=(*f_it)->key;
                std::vector<map_item*>::reverse_iterator next=f_it;
                --next;
               for (int n=0; n<2; n++) {
                  for (int m=0; m<2; m++) {
                      if ((*f_it)->matrix[n][m] == "O")
                         (*f_it)->matrix[n][m] = (*next)->key ;
                  }
               }
               
               for (std::map<std::string, micro_behavior*>::iterator it = key_address.begin(); it != key_address.end(); ++it) {
                      if (it->first==oldkey) {
                          (*it->second).mapper.insert(std::make_pair("START", (*f_it)->matrix));
                      }
                  }
                
            }  else  {  //middle micros
                 std::string oldkey=(*f_it)->key;
                
                std::vector<map_item*>::reverse_iterator next=f_it;
                --next;
                for (int n=0; n<2; n++) {
                  for (int m=0; m<2; m++) {
                      if ((*f_it)->matrix[n][m] == "O") {
                          
                          (*f_it)->matrix[n][m] = (*next)->key ;
                      }
                  }
                }
                
                for (std::map<std::string, micro_behavior*>::iterator it = key_address.begin(); it != key_address.end(); ++it) {
                      if (it->first==oldkey) {
                          std::vector<map_item*>::reverse_iterator next=f_it;
                          ++next;
                          (*it->second).mapper.insert(std::make_pair((*next)->key, (*f_it)->matrix));
                      }
                  }
            } 
            
            
            
            
        }
        
        std::cout << "After " << std::endl;
        
        for (std::vector<map_item*>::iterator f_it = items.begin(); f_it != items.end(); ++f_it) {
            (*f_it)->print();
            std::cout << "-----------------------------------------" << std::endl;
        }
        
    }    
       
        
        std::string id;
        micro_behavior *M;
        micro_behavior *T;
        micro_behavior *V;
        micro_behavior *X;
    };
    
    

int main(int argc, char** argv) {
        
        Macro_behavior MC("MC");
        std::cout << "M map----------------------------------------" << std::endl;
        MC.M->print_map();
        std::cout << "T map----------------------------------------" << std::endl;
        MC.T->print_map();
        std::cout << "V map----------------------------------------" << std::endl;
        MC.V->print_map();
        std::cout << "X map----------------------------------------" << std::endl;
        MC.X->print_map();
}
A legacy C-style array is not a copyable or moveable type. Use std::array<> instead.

Line 42:
1
2
// std::string matrix[N][N] ; // or use std::arr
std::array< std::array<std::string,N>, N > matrix ;


Line 74:
1
2
//for (std::map<std::string, std::string[2][2]>::iterator it = mapper.begin(); it != mapper.end(); ++it) {
for ( auto it = mapper.begin(); it != mapper.end(); ++it) {


Line 87:
1
2
        // std::map<std::string, std::string[2][2]> mapper;
        std::map<std::string, decltype(map_item::matrix) > mapper ;


auto http://www.stroustrup.com/C++11FAQ.html#auto
decltype http://www.stroustrup.com/C++11FAQ.html#decltype
Thank You Very Much for your time and interest. The program works with the corrections you suggested.

Chris
Remove the user defined destructor on line 25 // ~map_item(){ };
Rule of zero: http://en.cppreference.com/w/cpp/language/rule_of_three
Got it. Thanks. That's were I originally put my delete when I was using new. I guess the most basic lesson here would be that switching to std::array allowed for automatic allocation and deallocation of memory.

Can you spot any potential memory leaks in the above code? I know I will have to write a Macro_behavior destructor to delete the M,T,V,X micro_behaviors. I think any map_items created in line 67 is deallocated in the destructor in line 62.

Thanks
Chris

I switched to shared_ptrs so I dont have to worry about the memory leaks. It seems to have fixed some memory issues I could not track down.

Thanks for your time and interest
Chris
Topic archived. No new replies allowed.