Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
12 / 8 / 2
Регистрация: 14.01.2015
Сообщений: 31
1

2-мерные массивы: Вызов конструктора портит данные в других экземплярах

11.03.2015, 01:07. Показов 605. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Проблема: обнаружилось, что порой пропадают числа из существующих экземпляров класса. Числа (коллективно -- строками или колонками) заменяются на большие числа 3412341232, видимо, адреса. Портятся те массивы, которые переданы в функцию, и казалось бы, не должны изменяться.

TOC
-Подробности
-Случай 1: вызов конструктора другого экземпляра портит исходный экземпляр,
-Случай 2: внутри функции экземпляр не испорчен, сразу же после нее -- испорчен.


Подробности:

Создаю класс (далее nlNodeList) для работы с двумерными целочисленными массивами и посторонние функции, работающие с экземплярами класса -- например, выделение строки массива, склеивание блоков и прочие. Двумерный массив реализован через указатели. Функции принимают массивы как аргумент и возвращают объект класса.

C++
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
// Класс и его конструктор
// Ничего интересного тут нет, просто для справки 
class nlNodeList 
{
   public:
        long int listLength; // количество строк в массиве
        short int listWidth; // длина строки в массиве
        int **pp_C;          // собственно, массив с целыми числами
          nlNodeList(long int arg_nlLen, int arg_nlVar, int arg_nlDefault);
          ~nlNodeList(void);
          void nlWrite(long int arg_a, int arg_b, int arg_value);
          int nlRead(long int arg_a, int arg_b);
          void nlDisplay(void);
};  
    
nlNodeList::nlNodeList(long int arg_nlLen, int arg_nlVar, int arg_nlDefault = DEFAULTVALUE) 
{   
    listLength = arg_nlLen;
    listWidth = arg_nlVar;
    // Хотим пользоваться естественными индексами от 1 до N, поэтому столбцов и строк больше на одну
    pp_C = new int *[arg_nlLen+1];
    for (long int jc1 = 1; jc1 < arg_nlLen+1 ; jc1++ )
        {
            pp_C[jc1] = new int [ arg_nlVar+1 ];
            for (int jc2 = 1; jc2 < arg_nlVar+1 ; jc2++ )
            {
                pp_C[jc1][jc2] = arg_nlDefault;
            };
        };
    return;
};
Функции для работы с массивами берут объекты класса как аргументы и возращают объекты класса nlNodeList. Это удобно в дальнейшем для рекурсии. Функции вызываются также и внутри друг друга сообразно логике алгоритма. Допустим, nlNodeList Y = CloneNodeList(X) может использоваться внутри другой функции nlNodeList FunctionNodeList(nlNodeList arg_nlA) {...} для промежуточных вычислений и подготовке объекта класса nlNodeList для returnа из неё.

Поодиночке каждая функция работает нормально, возращает объекты класса, содержащие ожидаемые числовые значения.

Случай 1.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
// Пример одной из функций -- просто поячеечное копирование
nlNodeList CloneNodeList(nlNodeList arg_nlA)
{
    nlNodeList nlC = nlNodeList( arg_nlA.listLength , arg_nlA.listWidth ); // результат
    for (long int j1 = 1; j1 < arg_nlA.listLength+1 ; j1++ )
    {
        for (int j2 = 1; j2 < arg_nlA.listWidth+1 ; j2++ )
        {   
            nlC.nlWrite(j1,j2, arg_nlA.nlRead(j1,j2) );
        };
    };
    return nlC;
};
При отладке замечено, что исходная матрица arg_nlA портится строго на строке 4, в момент выполнения конструктора другого экземпляра того же класса nlC. До строки 4 arg_nlA --
https://www.cyberforum.ru/cgi-bin/latex.cgi?\begin{vmatrix}1 & 2 & 3 \\ 2 & 1 & 3\end{vmatrix},
после -- все числовые значения равны по умолчанию, как задается при инициализации конструктором (скажем, это 9). arg_nlA --
https://www.cyberforum.ru/cgi-bin/latex.cgi?\begin{vmatrix}9& 9& 9\\ 9 & 9 & 9\end{vmatrix}.
Поведение программы повторяется.

Случай 2.

C++
1
2
3
4
5
6
7
8
9
10
11
12
// 
nlNodeList FunctionOne(nlNodeList arg_F)        // функция берет аргумент arg_F и 
{
    // фрагмент
    
    nlNodeList nlResult1= nlNodeList(1, arg_F.listWidth, SOMEVALUE); // вспомогательный экземпляр создан конструктором
 
    intFOO = FunctionTwo(arg_F); // берет полученный arg_F и возвращает целое
 
    nlNodeList nlResult2 = FunctionThree(arg_F, intFOO, ANOTHERVALUE); // берет arg_F и возвращает экземпляр класса
 
    // далее следует рекурсивный вызов, однако, до него выполнение еще не доходило
При отладке замечено, что исходная матрица arg_F портится строго на строке 9.
В отличие от первого случая, от выполнения конструктора экземпляра того же класса nlResult1 на строке 6 ничего не портится. Внутри функции FunctionTwo на 8 строке также ничего не портится, arg_F выводится неизменным. Однако, по выходу из FunctionTwo она внезапно оказывается с испорченной первой строкой.

До строки 9 arg_nlA --
https://www.cyberforum.ru/cgi-bin/latex.cgi?\begin{vmatrix}1 & 2 & 3 \\ 2 & 1 & 3\end{vmatrix},
после -- испорчена первая строка arg_nlA --
https://www.cyberforum.ru/cgi-bin/latex.cgi?\begin{vmatrix}13456789 & 13456789 & 7575745 \\ 2 & 1 & 3\end{vmatrix}. Поведение повторяется, хотя числа бывают разными.

Затем программа вызывает APPCRASH и продолжения не следует.

Вопрос:
Как сохранять конкретные числа на своих местах? Как не допускать того, чтобы числовые значения, хранящиеся в экземплярах класса, сами по себе внезапно не заменялись на адреса, нули?

Задание учебное по рекурсивному разложению логических выражений. Поскольку будет использована рекурсия, то без многократных вызовов функций друг из друга, последовательных вызовов функций с одним экземпляром в качестве аргумента и возврата функциями объектов класса не обойтись.

Трудно внятно сформулировать проблему. В прикрепленных темах ответа не нашел.

Заранее спасибо.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.03.2015, 01:07
Ответы с готовыми решениями:

Вызов конструктора из конструктора и проверка правильности передаваемых параметров
Существует такой код: public Matrix(Double array) : this(array.GetLength(0),...

2-ух мерные массивы
Есть программа. Нужно сделать так , что бы в каждой строчке программа определяла максимальное...

2х мерные массивы
Скажите пожалуйста ПОЧЕМУ равны данные &quot;адресса&quot; есть массив a а в нем a+2=*(a+2) Как это?

2-х мерные массивы
В произвольном числовом двумерном массиве определить номер столбца, сумма элементов которого...

7
Модератор
Эксперт С++
13508 / 10758 / 6412
Регистрация: 18.12.2011
Сообщений: 28,725
11.03.2015, 08:37 2
Цитата Сообщение от Cene-O-Ralle Посмотреть сообщение
nlC.nlWrite(j1,j2, arg_nlA.nlRead(j1,j2) );
Зачем писать так хитро, если можно
C++
1
nlC.pp_C[j1][j2]=arg_nlA.pp_C[j1][j2];
А нулевые индексы в массивах Вы принципиально не используете?

Нужен код целиком.
0
18902 / 9860 / 2410
Регистрация: 30.01.2014
Сообщений: 17,305
11.03.2015, 08:55 3
Cene-O-Ralle, конструктор копирования и оператор присваивания, где они?
А вообще да, нужен код целиком.
0
12 / 8 / 2
Регистрация: 14.01.2015
Сообщений: 31
11.03.2015, 13:28  [ТС] 4
Всего: myprj.cpp, myprj.hpp, part1.txt.
* Код главного файла myprj.cpp:
Кликните здесь для просмотра всего текста
C++
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
/* CPP */
#include <iostream.h>
#include <fstream.h>
#include <iomanip.h>
#include <stdlib.h>
#include "myprj.hpp"
 
#define MAXVAR 20
#define MAXCUBES 1048576
#define INPUTFILENAME "part1.txt"
 
// 3 @10 = 11 @2 this value 11 means dont care,  bDNT
// 1 @10 = 01 @2 this value 01 means X,          bTRU
// 2 @10 = 10 @2 this value 10 means X-BAR,      bBAR
 
 
nlNodeList Complement(nlNodeList arg_F);
 
int main(void)
{
// ================= Prerare to read data ========
    cout << "\n=================================================================\n";
    cout << "                                                 MinGW2.95 " << __STDC_VERSION__ << "\n";
 
    ifstream inputFile;
    inputFile.open(INPUTFILENAME);
    if (!inputFile) 
    {
        cout << "Error reading input file: " << INPUTFILENAME << "\n";
        return 1;
    }
    cout << "Reading input file: " << INPUTFILENAME << "\n";
    
// ================= INIT ========================= 
 
    short int iVar;                     // 1 to MAXVAR = 20
    long int  iCubeCountF;              // 1 to MAXCUBES = 2^20
    long int  iCubeCountG;
    long int j1, j2, j3 = 0;            // counters 
    long int tmp = 0;
    
    inputFile >> iVar;
    inputFile >> iCubeCountF;
    iCubeCountG = iCubeCountF;
    
    cout << iVar << " varaibles were used, " << iCubeCountF << " cubes are listed in the input file";
 
    int *p_CubeLenF = new int[iCubeCountF+1];           // cube lengthes of F, F is as comes from the input
    int *p_CubeLenG = new int[iCubeCountG+1];           // cube lengthes of G, G is decoded into 00, 01, 11 notations
    int **pp_CubeF;                                 // size: iCubeCountF by p_CubeLenF[]
    int **pp_CubeG;                                 // size: iCubeCountF by iVar, filled with 3@10=11@2 by default
    pp_CubeF = new int *[iCubeCountF+1];
    pp_CubeG = new int *[iCubeCountG+1];
 
    for (long int j1 = 1; j1 < iCubeCountF+1 ; j1++ )       // Read data from the input and fill F and G
    {
        inputFile >> p_CubeLenF[j1];
        p_CubeLenG[j1] = iVar;
        pp_CubeF[j1] = new int [ p_CubeLenF[j1]+1 ];
        pp_CubeG[j1] = new int [ iVar+1 ];
        for (int j2 = 1; j2 < p_CubeLenG[j1]+1 ; j2++ )
        {
            pp_CubeG[j1][j2] = bDNT;                                 // 3 @10 = 11 @2- value 11 means dont care, bDNT
        };      
        for (int j2 = 1; j2 < p_CubeLenF[j1]+1 ; j2++ )
        {
            inputFile >> pp_CubeF[j1][j2];
            if ( pp_CubeF[j1][j2] > 0 ) 
                {
                     pp_CubeG[j1][ abs ( pp_CubeF[j1][j2] ) ] = bTRU;   // 1 @10 = 01 @2- value 01 means X, bTRU
                }
            if ( pp_CubeF[j1][j2] < 0 ) 
                {
                     pp_CubeG[j1][ abs ( pp_CubeF[j1][j2] ) ] = bBAR;   // 2 @10 = 10 @2- value 10 means X-BAR, bBAR
                }
            if ( pp_CubeF[j1][j2] == 0 ) { ; };                         // pp_CubeF[j1][j2] can not be zero due to convention   
        };
        ;
    }
// ========== End of INIT. F and G ready =========================
 
    nlNodeList A = nlNodeList(iCubeCountG, iVar);
    
    for (long int j1 = 1; j1 < A.listLength+1 ; j1++ )
    {
        for (int j2 = 1; j2 < A.listWidth+1 ; j2++ )
        {
            A.nlWrite(j1, j2, pp_CubeG[j1][j2] );
        };      
    }
    
    A.nlDisplayPCN();
    cout << "\nThe PCN cubes of A are displayed above this line.\n" ;
    cout << "\n" ;
     
    nlNodeList B1 = nlNodeList(1,1);
    B1 = Complement(A);
    B1.nlDisplayPCN();
    cout << "\nThe B1 is above.\n" ;
    
 
 
    cin.get();
 
 
 
 
// ========== CLEAR ===========================
    for (long int j1 = 1; j1 < iCubeCountF+1 ; j1++ )
    {
        delete [] pp_CubeF[ p_CubeLenF[j1] ];
    } 
    for (int j1 = 1; j1 < iCubeCountG+1 ; j1++ )
    {
        delete [] pp_CubeG[ p_CubeLenG[j1] ];
    } 
    delete [] p_CubeLenF;
    delete [] pp_CubeF;
    delete [] p_CubeLenG;
    delete [] pp_CubeG;
    inputFile.close();
    return 0;
}
 
 
nlNodeList Complement(nlNodeList arg_F)
{
    // 1. Check if F is simple enough
    
    int ifFsimple = 0;
    nlNodeList resultNL = nlNodeList(1, arg_F.listWidth, bNULL);
    
    //      1.1. Check if there were a 11..11 line
        for (long int j1 = 1; j1 < arg_F.listLength+1 ; j1++ )
        {
            int tmp = 0;
            for (int j2 = 1; j2 < arg_F.listWidth+1 ; j2++ )
                {
                    tmp = tmp + abs( arg_F.nlRead(j1,j2) - bDNT ) ; // diff with "11"
                };
            
            if (tmp == 0) 
                {
                    ifFsimple = 1;
                    resultNL = nlNodeList(1, arg_F.listWidth, bNULL);
                            cout << "\n==Complement result if 111111 line\n";
                            resultNL.nlDisplayPCN();
                            cin.get();
                    return resultNL; // no need to examine others
                }
        };
 
    //      1.2. Check if Length is zero
        if ( arg_F.listLength == 0)
        {
            ifFsimple = 1;
            resultNL = nlNodeList(1, arg_F.listWidth, bDNT );
                cout << "\n==Complement result at Zero length\n";
                resultNL.nlDisplayPCN();
                cin.get();
            return resultNL;
        };
    
    //      1.3. Check if Length is one
        if ( arg_F.listLength == 1)
        {
            ifFsimple = 1;
            resultNL = ComplementSingleLine(arg_F);
                cout << "\n==Complement result at Singleline and its result ... \n";
                resultNL.nlDisplayPCN();
                cin.get();
            return resultNL;
        };
        
    // 2. Find most binate X
    
        int splitX = 0;
        splitX = PickUpSplitVar(arg_F);
    
    // 3. Recursive call
                        arg_F.nlDisplay();
    
        
        nlNodeList nlCofFXTRU = Cofactor(arg_F, splitX, bTRU);
        nlNodeList nlCofFXBAR = Cofactor(arg_F, splitX, bBAR);
        
        nlNodeList nlP = Complement(nlCofFXTRU);
        nlNodeList nlN = Complement(nlCofFXBAR);
        
        nlNodeList nlXTRU = ExpandXtoLine(splitX, arg_F.listWidth, bTRU);
        nlNodeList nlXBAR = ExpandXtoLine(splitX, arg_F.listWidth, bBAR);
        
    
    
    // 4. ( AND(x, P) ) OR ( AND(xbar, Pbar) )
    
        nlNodeList nlXP = ANDBlockAndLine(nlXTRU, nlP);
        nlNodeList nlXN = ANDBlockAndLine(nlXBAR, nlN);
        
        resultNL = ORAppendTwoBlocks(nlXP, nlXN);
                
    
    cout << "\n=Complement result\n";
    resultNL.nlDisplayPCN();
    cin.get();
    return resultNL;
 
}


Добавлено через 3 минуты
* Код myprj.hpp
Кликните здесь для просмотра всего текста
C++
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
/* H E A D E R */
 
#define bDNT 3
#define bTRU 1
#define bBAR 2
#define bNULL 0
 
/* The 2D arrays carry numbers 0, 1, 2, 3 (bNULL, bTRU, bBAR, bDNT) 
   which are interpreted as "00", "01", "10" and "11" */
 
#include <stdio.h>
 
#define SILENTDEBUGMODE 0
#define SILENTDEBUGMODE2 0
 
 
/* 
   =======================================================================================================================
   ===          NON CLASS MEMBERS                       ======================
   =======================================================================================================================
*/
 
int inttopcn(int arg_int)
{
    return 10*div(arg_int,2).quot+div(arg_int,2).rem; // switch from 0,1,2,3 notation to 00,01,10,11
};
 
int pcntoint(int arg_pcn)
{
    return 2*div(arg_pcn,10).quot+div(arg_pcn,10).rem; // switch from 00,01,10,11 notation to 0,1,2,3 
};
 
int pcnand(int arg_pcn1, int arg_pcn2) // just AND operation over 00,01,10,11 notations 
{
    int tmp2 = 0;
    int tmp = inttopcn(arg_pcn1) * 100 + inttopcn(arg_pcn2);
    switch (tmp){
        case         00: tmp2 = 00; break;
        
        case  01*100+01: tmp2 = 01; break;
        case  01*100+10: tmp2 = 00; break;
        case  01*100+11: tmp2 = 01; break;
        
        case  10*100+01: tmp2 = 00; break;
        case  10*100+10: tmp2 = 10; break;
        case  10*100+11: tmp2 = 10; break;
        
        case  11*100+01: tmp2 = 01; break;
        case  11*100+10: tmp2 = 10; break;
        case  11*100+11: tmp2 = 11; break;
        
        default:     tmp2 =  0; 
        };
    return pcntoint(tmp2);
};
0
12 / 8 / 2
Регистрация: 14.01.2015
Сообщений: 31
11.03.2015, 13:34  [ТС] 5
Продолжение
Кликните здесь для просмотра всего текста
C++
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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
/* 
   ===========================================
   ===          CLASS MEMBERS                           =======================
   ============================================
*/
 
class nlNodeList 
{
   public:
        long int listLength;
        short int listWidth;
        int **pp_C;
          nlNodeList(long int arg_nlLen, int arg_nlVar, int arg_nlDefault);
          ~nlNodeList(void);
          void nlWrite(long int arg_a, int arg_b, int arg_value);
          int nlRead(long int arg_a, int arg_b);
          void nlDisplay(void);
          void nlDisplayPCN(void);
};  
    
nlNodeList::nlNodeList(long int arg_nlLen, int arg_nlVar, int arg_nlDefault = bDNT) 
{   // nlNodeList class constructor. The 3rd param sets the elements to be 3 = "11" by default.
    listLength = arg_nlLen;
    listWidth = arg_nlVar;
    pp_C = new int *[arg_nlLen+1];
    for (long int jc1 = 1; jc1 < arg_nlLen+1 ; jc1++ )
        {
            pp_C[jc1] = new int [ arg_nlVar+1 ];
            for (int jc2 = 1; jc2 < arg_nlVar+1 ; jc2++ )
            {
                pp_C[jc1][jc2] = arg_nlDefault;             // bDNT = 3 = "11"
            };
        };
    return;
};
 
nlNodeList::~nlNodeList(void) 
{   // nlNodeList class destructor. Unallocates the memory.
    for (long int jc1 = 1; jc1 < listLength+1 ; jc1++ )
    {
        delete [] pp_C[ jc1 ];
    } 
    delete [] pp_C;
    return;
};
 
//---------------------------------------------------------------------------
 
void nlNodeList::nlWrite(long int arg_a, int arg_b, int arg_value)
{
    pp_C[arg_a][arg_b] = arg_value;
    return;
};
 
int nlNodeList::nlRead(long int arg_a, int arg_b)
{
    return pp_C[arg_a][arg_b];
};
 
void nlNodeList::nlDisplay(void)
{
    for (long int jc11 = 1; jc11 < listLength+1 ; jc11++ )
    {
        cout << "\n";
        for (int jc21 = 1; jc21 < listWidth+1 ; jc21++ )
        {
            cout << setw(1) << setfill( '0' ) << nlRead(jc11, jc21) << " " ;
        };      
    }
    return;
};
 
void nlNodeList::nlDisplayPCN(void)
{   // same as nlDisplay, but in 00, 01, 10, 11 notation
    for (long int jc11 = 1; jc11 < listLength+1 ; jc11++ )
    {
        cout << "\n";
        for (int jc21 = 1; jc21 < listWidth+1 ; jc21++ )
        {
            cout << setw(2) << setfill( '0' ) << inttopcn( nlRead(jc11, jc21) ) << " " ;
        };      
    }
    return;
};
 
/*  ========================================================
*/
 
 
nlNodeList CloneNodeList(nlNodeList arg_nlA) 
{
    if (SILENTDEBUGMODE == 0) 
    {
        cout << "\nCloneNodeList called...";
        cout << "\n  Original NL to be cloned\n";
        arg_nlA.nlDisplay();
        cout << "\n   (a) A(1,1) is " << arg_nlA.nlRead(1,1) << "\n";
    }
    long int tmp1, tmp2;
    
    tmp1 = arg_nlA.listLength; // a bit more complicated code to make sure where nlA had gotten spoilt
    tmp2 = arg_nlA.listWidth;
                cout << "(" << tmp1 << "," << tmp2 << ")";
                cout << "\n    (b) A(1,1) is  " << arg_nlA.nlRead(1,1) << "\n";
    
    nlNodeList nlC = nlNodeList( tmp1 , tmp2 );
                cout << "\n    (c) A(1,1) is " << arg_nlA.nlRead(1,1) << "\n"; // New constructor fflushes ARG-nlA values into bDNT = 3.
                arg_nlA.nlDisplay();
    for (long int j1 = 1; j1 < tmp1+1 ; j1++ )
    {
        for (int j2 = 1; j2 < tmp2+1 ; j2++ )
        {   
            nlC.nlWrite(j1,j2, arg_nlA.nlRead(j1,j2) );
        };
    };
    
    if (SILENTDEBUGMODE == 0) 
    {
        cout << "\nCloneNodeList returning...";
        cout << "\n  Output NL which was cloned\n";
        nlC.nlDisplay();
    }
    return nlC;
};
 
//------------------------------------------
 
nlNodeList StrikeOutFirstLine(nlNodeList arg_nlA)
{
    if (SILENTDEBUGMODE == 0) 
    {
        cout << "\nStrikeOutFirstLine called...";
        cout << "\n  Original NL to be StrikeOutFirstLined\n";
        arg_nlA.nlDisplay();
    }
    
    nlNodeList nlC = nlNodeList( arg_nlA.listLength - 1, arg_nlA.listWidth); // magic one
    for (long int j1 = 1; j1 < nlC.listLength+1 ; j1++ )
    {
        for (int j2 = 1; j2 < nlC.listWidth+1 ; j2++ )
        {
            nlC.nlWrite(j1,j2, arg_nlA.nlRead(j1+1,j2) ); // magic one
        };
    };
    if (SILENTDEBUGMODE == 0)   
    {
        cout << "\nStrikeOutFirstLine returning...";
        cout << "\n  Output NL which was StrikeOutFirstLined\n";
        nlC.nlDisplay();
    }
    return nlC;
};
 
//-------------------------------------------------------
 
 
nlNodeList ORAppendTwoBlocks(nlNodeList arg_nlA, nlNodeList arg_nlB)
{
    if (SILENTDEBUGMODE == 0) 
    {
        puts("\nORAppendTwoBlocks called...");
        cout << "\n  Original NLs to be ORAppendTwoBlocks\n";
        arg_nlA.nlDisplay();
        arg_nlB.nlDisplay();
    }
    
    if (arg_nlA.listWidth != arg_nlA.listWidth) 
    {
        cout << "\nORAppendTwoBlocks interrupts due to the size mismatch...";
        cin.get();
        exit(1);
        return nlNodeList(0,0);
        
    }
    
    nlNodeList nlC = nlNodeList( arg_nlA.listLength + arg_nlB.listLength , arg_nlA.listWidth);
    long int tmp;
    for (long int j1 = 1; j1 < arg_nlA.listLength+1 ; j1++ )
    {
        if ( arg_nlA.listLength == 0) continue; 
        for (int j2 = 1; j2 < arg_nlA.listWidth+1 ; j2++ )
        {
            nlC.nlWrite(j1,j2, arg_nlA.nlRead(j1,j2) );
        };
        tmp = j1;   
    };
    for (long int j1 = 1; j1 < arg_nlB.listLength+1 ; j1++ )
    {
        if ( arg_nlB.listLength == 0) continue;
        for (int j2 = 1; j2 < arg_nlB.listWidth+1 ; j2++ )
        {
            nlC.nlWrite(j1+tmp,j2, arg_nlB.nlRead(j1,j2) );
        };  
    };  
    if (SILENTDEBUGMODE == 0) 
    {
        puts("\nORAppendTwoBlocks returning...");
        cout << "\n  Output NL which was ORAppendTwoBlocked\n";
        nlC.nlDisplay();
    }
    return nlC;
};
 
//---------------------------------------------------------------
 
nlNodeList ANDTwoLines(nlNodeList arg_nlA, long int arg_indexA, nlNodeList arg_nlB, long int arg_indexB)
{
    if (SILENTDEBUGMODE == 0) 
    {
        puts("\nANDTwoLines called...");
        cout << "\n  Original NL1 to be ANDTwoLines, at " << arg_indexA << "\n";
        arg_nlA.nlDisplay();
        cout << "\n  Original NL2 to be ANDTwoLines, at " << arg_indexB << "\n";
        arg_nlB.nlDisplay();
    }
 
    int envirMaxVar = arg_nlA.listWidth;
    nlNodeList nlC = nlNodeList(1, envirMaxVar);
    for (int j1 = 1; j1 < envirMaxVar+1 ; j1++ )
    {
        nlC.nlWrite(1, j1, pcnand( arg_nlA.nlRead(arg_indexA, j1), arg_nlB.nlRead(arg_indexB, j1) ) );
    }
    if (SILENTDEBUGMODE == 0) 
    {
        puts("\nANDTwoLines returning...");
        cout << "\n  Output NL which was ANDTwoLines\n";
        nlC.nlDisplay();
    }
    return nlC;
};
 
//-----------------------------------------------------
 
nlNodeList ANDBlockAndLine(nlNodeList arg_nlA, nlNodeList arg_nlB)
{
    // FIRST arg_nlA must be a single line
    if (SILENTDEBUGMODE == 0) 
    {
        puts("\nANDBlockAndLine called...");
        cout << "\n  Original NL1 to be ANDBlockAndLine\n";
        arg_nlA.nlDisplay();
        cout << "\n  Original NL2 to be ANDBlockAndLine\n";
        arg_nlB.nlDisplay();
    }
    
    nlNodeList nlC = nlNodeList(0,0);
    if (arg_nlA.listLength != 1) 
    {
        cout << "\nANDBlockAndLine interrupts due to the size mismatch...";
        cout << "\nFirst argument to be a line and is ...";
        arg_nlA.nlDisplayPCN();
        cout << "\nSecond argument is ...";
        arg_nlB.nlDisplayPCN();
        
        cin.get();
        exit(1);
        return nlC;
    }
    
    int envirMaxVar = arg_nlB.listWidth;
    nlC = nlNodeList(1, envirMaxVar);
    for (long int j1 = 1; j1 < arg_nlB.listLength+1 ; j1++ )
    {
        for (int j2 = 1; j2 < arg_nlB.listWidth+1 ; j2++ )
        {
            nlC.nlWrite(j1,j2, pcnand( arg_nlB.nlRead(j1,j2) , arg_nlA.nlRead(1,j2) ) );
        };
    };
    if (SILENTDEBUGMODE == 0) 
    {
        puts("\nANDBlockAndLine returning...");
        cout << "\n  Output NL which was ANDBlockAndLined\n";
        nlC.nlDisplay();
    }
    return nlC;
};
 
//-------------------------------------------------
 
 
nlNodeList ExtractOneLine(nlNodeList arg_nlAexol, long int arg_indexA)
{
    if (SILENTDEBUGMODE == 0)
    {
        puts("\nExtractOneLine called...");
        cout << "\n  Original NL1 to be ExtractOneLined, at " << arg_indexA << "\n";
        arg_nlAexol.nlDisplay();
    }
    int envirMaxVar = arg_nlAexol.listWidth;
    nlNodeList nlC = nlNodeList(1, envirMaxVar);
    for (int j1 = 1; j1 < envirMaxVar+1 ; j1++ )
    {
        nlC.nlWrite(1, j1, arg_nlAexol.nlRead(arg_indexA, j1 ) );
    }
   cout << " Extracted line is -- ";
   nlC.nlDisplayPCN();
   
    if (SILENTDEBUGMODE == 0) 
    {
        puts("\nExtractOneLine returning...");
        cout << "\n  Output NL which was ExtractOneLined\n";
        nlC.nlDisplay();
    }
    return nlC;
};
 
//-------------------------------------------------------
 
nlNodeList ExpandXtoLine(int arg_indexX, int arg_envirMaxVar, int arg_bool)
{
    if (SILENTDEBUGMODE == 0) 
    {
        puts("\nExpandXtoLine called...");
        cout << "\n  Original index to be ExpandXtoLined, is " << arg_indexX << ", and TRU(1)/BAR(2) is " << arg_bool << "\n";
    }
    nlNodeList nlC = nlNodeList(1, arg_envirMaxVar, bDNT);
    nlC.nlWrite(1, arg_indexX, arg_bool );
    if (SILENTDEBUGMODE == 0) 
    {
        puts("\nExpandXtoLine returning...");
        cout << "\n  Output NL which was ExpandXtoLined\n";
        nlC.nlDisplay();
    }
    return nlC;
};
 
//-----------------------------------------------
 
nlNodeList KillZeroLines(nlNodeList arg_nlA)
{
    if (SILENTDEBUGMODE == 0) 
    {
        puts("\nKillZeroLines called...");
        cout << "\n  Original NL to be KillZeroLined\n";
        arg_nlA.nlDisplay();
    }
    int flag = 0;
    nlNodeList nlC = nlNodeList(1, arg_nlA.listWidth); // initiate with 1, so use StrikeOutFirstLine at last 
    for (long int j1 = 1; j1 < arg_nlA.listLength+1 ; j1++ )
    {
        flag = 1;
        for (int j2 = 1; j2 < arg_nlA.listWidth+1 ; j2++ )
        {
            if (arg_nlA.nlRead(j1,j2) == bNULL ) flag = flag*0;
        };
        
        if (flag != 0 )  nlC = ORAppendTwoBlocks(nlC, ExtractOneLine(arg_nlA, j1) );
    }
    
    nlNodeList nlD = StrikeOutFirstLine(nlC);
    nlC = CloneNodeList(nlD);
    if (SILENTDEBUGMODE == 0) 
    {
        puts("\nKillZeroLines returning...");
        cout << "\n  Output NL which was KillZeroLined\n";
        nlC.nlDisplay();
    }
    return nlC;
};
 
//-----------------------------------------------
 
nlNodeList Cofactor(nlNodeList arg_nlA, int arg_indexX, int arg_bool)
{
    if (SILENTDEBUGMODE == 0) 
    {
        puts("\nCofactor called...");
        cout << "\n  Original NL to be Cofactored wrt to " << arg_indexX << ", and TRU(1)/BAR(2) is " << arg_bool << "\n";
        arg_nlA.nlDisplay();
    }
    nlNodeList nlC = CloneNodeList(arg_nlA);
    for (long int j1 = 1; j1 < arg_nlA.listLength+1 ; j1++ )
    {
        if  ( arg_bool == bTRU ) 
            {
                if  ( arg_nlA.nlRead(j1, arg_indexX) == bBAR ) nlC.nlWrite(j1, arg_indexX, bNULL);
                if  ( arg_nlA.nlRead(j1, arg_indexX) == bTRU ) nlC.nlWrite(j1, arg_indexX, bDNT );
            }
        if  ( arg_bool == bBAR )
            {
                if  ( arg_nlA.nlRead(j1, arg_indexX) == bBAR ) nlC.nlWrite(j1, arg_indexX, bDNT );
                if  ( arg_nlA.nlRead(j1, arg_indexX) == bTRU ) nlC.nlWrite(j1, arg_indexX, bNULL);
            }       
    }
    
    nlNodeList nlD = KillZeroLines(nlC);
    nlC = CloneNodeList(nlD);
    if (SILENTDEBUGMODE == 0) 
    {
        puts("\nCofactor returning...");
        cout << "\n  Output NL which was Cofactored wrt to " << arg_indexX << ", and TRU(1)/BAR(2) is " << arg_bool << "\n";
        nlC.nlDisplay();
    }
    return nlC;
};
 
 
//---------------------------------------------------
 
nlNodeList ComplementSingleLine(nlNodeList arg_nlA)
{
    if (SILENTDEBUGMODE == 0)   
    {
        puts("\nComplementSingleLine called...");
        cout << "\n  Original NL to be ComplementSingleLined\n";
        arg_nlA.nlDisplay();
    }
    nlNodeList nlC = nlNodeList(1, arg_nlA.listWidth, bNULL);       // initiate with 1, so use StrikeOutFirstLine at last 
    
    if ( arg_nlA.listLength != 1 )
        {
            cout << " Complementing error. More than one cube found. ";
            cin.get();
            exit(1);
            return nlC;
        };
    
    // We have a line 11 10 01 11 ... 01
    // Here 11 is skipped, 10 turns to 01, 01 turns to 10.
    
    for (int j1 = 1; j1 < arg_nlA.listWidth+1  ; j1++)
        {
            //cout << "nlC is ";
            //nlC.nlDisplay();
            int tmp = 0;
            if ( arg_nlA.nlRead(1, j1) == bDNT ) continue;
            if ( arg_nlA.nlRead(1, j1) == bTRU ) { tmp = bBAR; };
            if ( arg_nlA.nlRead(1, j1) == bBAR ) { tmp = bTRU; };
            if ( arg_nlA.nlRead(1, j1) == bNULL) continue;
            
            nlNodeList nlB = ExpandXtoLine(j1, arg_nlA.listWidth, tmp );
            //cout << "nlB is ";
            //nlB.nlDisplay();
            nlNodeList nlD = ORAppendTwoBlocks(nlC, nlB);
            //cout << "nlD is ";
            //nlD.nlDisplay();
            nlC = CloneNodeList(nlD);
        };
    
    nlNodeList nlD = StrikeOutFirstLine(nlC);
    nlC = CloneNodeList(nlD);
    
    puts("\nComplementSingleLine returning ...\n");
    cout << "\nThis line is ... ";
    arg_nlA.nlDisplayPCN();
    cout << "\nThe result is ... ";
    nlC.nlDisplayPCN();
    cout << "\n ==Ok";
    
    if (SILENTDEBUGMODE == 0)   
    {
        puts("\nComplementSingleLine returning...");
        cout << "\n  Output NL which was ComplementSingleLined\n";
        nlC.nlDisplay();
    }
    //cin.get();
    return nlC;
};
 
//-------------------------------------------
 
int PickUpSplitVar(nlNodeList arg_nlA)
{
        /*
        Priority List to Be Done
        1) Binate
            *1.1) Most popular
             1.2) Min abs( bTRU - bBAR ) value
             1.3) The smallest index
        2) Unate
             2.1) Most popular
             2.2) The smallest index
    
        Now uses 1.1 and the largest index
        */
    if (SILENTDEBUGMODE == 0)
    {
        puts("\nPickUpSplitVar called...");
        cout << "\n  Original NL to be analysed for PickUpSplitVar\n";
        arg_nlA.nlDisplay();
    }
    long int tmp;
    int indexX;
    
    nlNodeList nlRankPopular = nlNodeList(1, arg_nlA.listWidth, bNULL); // to carry the ranks
    
 
    // 1.1 Find most popular
    
    for (int j2 = 1; j2 < arg_nlA.listWidth+1 ; j2++ )
    {
        tmp = 0;
        indexX = 0;
 
        for (long int j1 = 1; j1 < arg_nlA.listLength+1 ; j1++ )
        {
            if  ( (arg_nlA.nlRead(j1,j2) == bTRU ) || (arg_nlA.nlRead(j1,j2) == bBAR ) ) 
                {
                    tmp = tmp + 1 ;
                    nlRankPopular.nlWrite(1, j2, tmp);
                };
        }
    }
    
    for (int j2 = 1; j2 < arg_nlA.listWidth+1 ; j2++ )
    {
        if ( nlRankPopular.nlRead(1, j2) > tmp ) 
            {
                tmp = nlRankPopular.nlRead(1, j2);
                indexX = j2;
            }
    }
    
    // End of 1.1 Find most popular 
    
    if ( indexX == 0 ) indexX = 1;
 
 
    if (SILENTDEBUGMODE == 0)   
    {
        cout << "\nPickUpSplitVar returning with result - " << indexX << ", the ranks were found - ";
        nlRankPopular.nlDisplay();
        cout << "\n  For the matrix ";
        arg_nlA.nlDisplayPCN();
        cin.get();
    }
 
    return indexX;
 
}
 
//-------------------------------------


Чтение идет из текстового файла part1.txt, в котором: первая строка = число переменных (будет использовано как listWidth - ширина массива), вторая строка = число последущих строк (будет listLength - длина массива), первые цифры в каждой строке = число непустых элементов в этой строке. Числа дают индексы непустых переменных.
https://www.cyberforum.ru/cgi-bin/latex.cgi?x \rightarrow 01, https://www.cyberforum.ru/cgi-bin/latex.cgi?\bar{x} \rightarrow 10, https://www.cyberforum.ru/cgi-bin/latex.cgi?\bar{x}+x=1 \rightarrow 11

Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
5
3
3 2 3 4
2 -1 5
3 1 -3 -4


Копия во вложении.
Вложения
Тип файла: zip myprj.zip (5.3 Кб, 5 просмотров)
0
Модератор
Эксперт С++
13508 / 10758 / 6412
Регистрация: 18.12.2011
Сообщений: 28,725
11.03.2015, 14:37 6
После исправления ошибок компиляции у меня программа слетает на строке
A.nlDisplayPCN();
cout << "\nThe PCN cubes of A are displayed above this line.\n" ;
cout << "\n"
Ошибки компиляции были типа
C++
1
2
            exit(1);
            return nlC; // эта строка недостижима
И еще некоторым переменным не были присвоены начальные значения
0
18902 / 9860 / 2410
Регистрация: 30.01.2014
Сообщений: 17,305
11.03.2015, 16:31 7
Cene-O-Ralle, в целом, как я и говорил, необходимо добавить классу конструктор копирования и оператор присваивания. Ты ими в программе активно пользуешься, но при это не определил. А оператор и конструктор, сгенерированные компилятором по умолчанию, не в курсе про то, как правильно копировать твой объект класса nlNodeList. Поэтому выполняется простое почленное копирование, что в итоге означает разделение владение ресурса между разными объектами, попытка двойного освобождения памяти и многие другие неприятности.
Кликните здесь для просмотра всего текста
C++
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
class nlNodeList
{
public:
    int listLength;
    int listWidth;
 
    nlNodeList(int arg_nlLen, int arg_nlVar, int arg_nlDefault);
 
    nlNodeList(nlNodeList const & other);
    nlNodeList & operator=(nlNodeList const & other);
 
    ~nlNodeList(void);
    void nlWrite(int arg_a, int arg_b, int arg_value);
    int  nlRead(int arg_a, int arg_b);
    void nlDisplay(void);
    void nlDisplayPCN(void);
 
private:
    void swap(nlNodeList & other);
 
    int ** pp_C;
};
 
void nlNodeList::swap(nlNodeList & other)
{
    int ** pp = other.pp_C;
    other.pp_C = pp_C;
    pp_C = pp;
    int lLen = other.listLength;
    other.listLength = listLength;
    listLength = lLen;
    int lWid = other.listWidth;
    other.listWidth = listWidth;
    listWidth = lWid;
}
 
nlNodeList::nlNodeList(int arg_nlLen, int arg_nlVar, int arg_nlDefault = bDNT)
    : listLength(arg_nlLen), listWidth(arg_nlVar)
    , pp_C(new int *[arg_nlLen + 1])
{
    // nlNodeList class constructor. The 3rd param sets the elements to be 3 = "11" by default.
    for(int jc1 = 1; jc1 < listLength + 1; jc1++ )
    {
        pp_C[jc1] = new int [ listWidth + 1 ];
        for(int jc2 = 1; jc2 < listWidth + 1; jc2++ )
        {
            pp_C[jc1][jc2] = arg_nlDefault;             // bDNT = 3 = "11"
        }
    }
}
 
nlNodeList::nlNodeList(nlNodeList const & other)
    : listLength(other.listLength), listWidth(other.listWidth)
    , pp_C(new int *[listLength + 1])
{
    for(int jc1 = 1; jc1 < listLength + 1 ; jc1++ )
    {
        pp_C[jc1] = new int[listWidth + 1];
        for(int jc2 = 1; jc2 < listWidth + 1; jc2++ )
        {
            pp_C[jc1][jc2] = other.pp_C[jc1][jc2];              // bDNT = 3 = "11"
        }
    }
}
 
nlNodeList & nlNodeList::operator=(nlNodeList const & other)
{
    if(this != &other)
    {
        nlNodeList(other).swap(*this);
    }
    return *this;
}
 
nlNodeList::~nlNodeList(void)
{
    // nlNodeList class destructor. Unallocates the memory.
    for(int jc1 = 1; jc1 < listLength + 1 ; jc1++ )
    {
        delete [] pp_C[ jc1 ];
    }
    delete [] pp_C;
}

Идея с индексами с единицы - крайне неудачная. По крайней мере такая реализация. Можно было бы инкапсулировать это поведение с помощью методов nlWrite и nlRead, а в остальных местах программы не делать постоянные +1.

Добавлено через 6 минут
Еще есть ошибка в функции ANDBlockAndLine.
C++
1
2
3
4
5
6
7
8
9
10
11
    int envirMaxVar = arg_nlB.listWidth;
    nlC = nlNodeList(1, envirMaxVar); /* здесь стоит 1, но в качестве индекса nlWrite может передаваться число 2, 
что выходит за пределы допустимого диапазона. Подозреваю, что у уважаемого zss программа упала именно 
из-за этого. Тебе нужно что-то с этим сделать :) */
    for (int j1 = 1; j1 < arg_nlB.listLength + 1 ; j1++ )
    {
        for (int j2 = 1; j2 < arg_nlB.listWidth + 1 ; j2++ )
        {
            nlC.nlWrite(j1, j2, pcnand( arg_nlB.nlRead(j1,j2),  arg_nlA.nlRead(1,j2) ) );
        }
    }
А, да - передача больших объектов по ссылке - это хорошо. Не пренебрегай этим.
0
12 / 8 / 2
Регистрация: 14.01.2015
Сообщений: 31
21.03.2015, 18:51  [ТС] 8
Спасибо за помощь.
Исправил, но APPCRASH не побежден.
Не до конца понимаю: откуда компилятору становится нужен конструктор копирования и оператор присваивания, если я их не вызывал и пользовался числ. значениями в суррогатном копировании CloneNodeList ? -- или же содержимое объекта nlNodeList arg_nlA в нем передавалось как указатели по непониманию?
0
21.03.2015, 18:51
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.03.2015, 18:51
Помогаю со студенческими работами здесь

Вызов конструктора из конструктора - ошибка
Айм водеринг. Но разве из одного конструктора нельзя вызвать другой (из StadoOvechek() вызвать...

Одномерный и двух мерные массивы
У меня проблема в двух задачах, ребят помогите пожалуйста, недавно начал изучать С# 1....

Строки,процедуры,записи,массивы 1,2 мерные
Здравствуйте помогите решить следующие задачи.Очень срочно нужно!!! 1)Дан текст . Подсчитать...

1- и 2-мерные массивы. Описание полей и переменных.
Ребят! Помогите, пожалуйста. У меня есть пара решенных задач, но в связи с тем, что я блондинка,...

Как сортируются двух и более мерные массивы?
*************************************** *Как сортируются двух и более мерные массивы?*...

В разных экземплярах класса одинаковые данные
Проблема в следующем - есть класс Векторы, создаю в главном классе 3 вектора и заношу в два из них...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru