Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.69/29: Рейтинг темы: голосов - 29, средняя оценка - 4.69
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484

Оценка кода

28.01.2020, 22:43. Показов 6983. Ответов 123
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, прошу вас всех оценить мой код , по возможности дать советы что так , а что не так и как это исправить либо в каком направлении смотреть , это моя первая попытка создать что-то не ради забавы , а чтобы использовать это в реальной жизни. Сразу скажу что еще не все доделал что хотел бы. Это декодер asn1.der , данные передаются в decode() в виде BLOB конвертированного в массив знаков.
header
Кликните здесь для просмотра всего текста
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
#include <iostream>
#include "string.h"
 
#define ENDOFARRAY -1
 
#define INTEGER 0x02
#define OCTET_STRING 0x04
#define OBJECT_IDENTIFIER 0x06
#define SEQUENCE 0x30
 
#define SETBIT(number,bit) ((number) |= (pow(2,bit)))
#define CHECKBIT(number,bit) ((number) & (1 << (bit)))
 
class decoder{
    public:
        decoder();
 
        ~decoder();
 
        char * decode(const unsigned char * ,int,char * cipherT = nullptr, char * Other = nullptr);
 
        void decode64(const char * ,char * cipherT = nullptr, char * Other = nullptr);
 
    private:
        //Calculates number in power
        int pow(int,int);
 
        char* IntToHexChar(int);
 
        void AppendOctetString(int);
 
        int CalculateLongSID(int&);
 
        //Calculates all decimal values of indentifier
        void CalculateIdentifier(int);
 
        //Calculates first byte of indentifier which is decoded to two values
        void CalculateIdentifierFirstByte();
 
        //Convert byte array to decimal value
        int CalculateBytes(int);
 
        //Decoding encoded ans1.der string
        void ParseData();
 
        //Appends passed array with new array
        char * Append(char *,char *);
 
        //Decodes length of front bytes
        int ParseLength(int);
 
        //Handles Octet String
        void OctetStringHandler();
 
        //Handles Object Indentifier
        void ObjectIdentifierHandler();
 
        //Handles Integer
        void IntegerHandler();
 
        //Handles Sequance
        void SequenceHandler();
 
        //Converts char array to int array
        void ToIntArray();
 
        //Copies value of passed array and returns new created one with same values
        const unsigned char *  NewArr(const unsigned char* );
 
        //Byte array as integers
        int * IntByteArray = nullptr;
 
        //Pointer to IntByteArray which is used to move through array
        int * pArr = nullptr;
 
        //Byte array as char
        const unsigned char * CharByteArray = nullptr;
 
        //The result decoded string
        char * Result = new char[1]{};
 
        //Size of IntByteArray
        int size = 0;
};

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
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
#include "asn1der.h"
 
decoder::decoder(){
}
 
 
decoder::~decoder(){
    if(CharByteArray)
        delete[] CharByteArray;
    if(IntByteArray)
        delete[] IntByteArray;
}
 
 
char * decoder::Append(char * dst,char * src){  
     int dstlen = strlen(dst),srclen =  strlen(src);
     char* temp = new char[dstlen+srclen+1]{};
     memcpy(temp, dst, dstlen);
     strcat(temp,src);
     delete[] dst;
     return temp;
}
 
 
const unsigned char *  decoder::NewArr(const unsigned char* arr) {
    unsigned char * temp = new unsigned char[size+1]{};
    for(int i = 0;i < size;++i){
        temp[i] = arr[i];
    }
    return temp;
}
 
 
void decoder::ToIntArray(){
    IntByteArray = new int[size+1]{};
    for(int i = 0;i<size;++i){
        IntByteArray[i] = (unsigned int)CharByteArray[i];
    }
    IntByteArray[size] = -1;
    pArr = IntByteArray;
}
 
 
void decoder::ParseData(){
    switch (*pArr)
    {
        case ENDOFARRAY:
            break;
        case INTEGER:
            IntegerHandler();
            ParseData();
            break;
        case OCTET_STRING:
            OctetStringHandler();
            ParseData();
            break;
        case OBJECT_IDENTIFIER:
            ObjectIdentifierHandler();
            ParseData();
            Result = Append(Result,const_cast<char *>("}"));
            break;
        case SEQUENCE:
            SequenceHandler();
            ParseData();
            Result = Append(Result,const_cast<char *>("\n}"));
            break;
        default:
            break;
    }
}
 
 
char * decoder::decode(const unsigned char * Text,int length,char * cipherT, char * Other){
    size = length;
      CharByteArray = NewArr(Text);
      ToIntArray();
      try{
          ParseData();
      }
      catch(const char* exception){
         std::cout << exception;
          return nullptr;
      }
      return Result;
}
 
 
int decoder::ParseLength(int num){
    num &= 63;
    return num;
}
 
 
int decoder::pow(int num, int times){
    if(times == 0)
        return 1;
    if(times == 1)
        return 2;
    if(times > 1)
        return num*pow(num,--times);
}
 
 
int decoder::CalculateBytes(int len){
    int calculated = 0,power = len*8-1;
    for(int i = 0;i < len && ++pArr;i++){
 
        if(*pArr == -1 )
            throw "CalculateBytes error";
 
        for(int q = 7;q >= 0;--q){
            if(CHECKBIT(*pArr,q)){
                calculated += pow(2,power);
            }
            --power;
        }
    }
    return calculated;
}
 
 
void decoder::CalculateIdentifierFirstByte(){ //there are only three types of first node 1,2,3 , first byte is calculated with (firstnode*40 + secondnode)
    if(*++pArr < 80){ //if first byte is less than 80 it means that first node is 1
 
        if(*pArr == -1 )
            throw "CalculateIndentifierFirstByte error";
 
        Result = Append(Result,const_cast<char *>((std::to_string(1) + ".").c_str()));
        Result = Append(Result,const_cast<char *>((std::to_string(*pArr-40)+ ".").c_str())); //if first node is 1 the second node is : number - (firstnode * 40)
        return;
    }else if (*pArr < 120) //means that first node is 2
    {
        Result = Append(Result,const_cast<char *>((std::to_string(2) + ".").c_str()));
        Result = Append(Result,const_cast<char *>((std::to_string(*pArr-80)+ ".").c_str())); //if first node is 1 the second node is : number - (firstnode * 40)
        return;
    }else // first node is 3
    {
        Result = Append(Result,const_cast<char *>((std::to_string(3) + ".").c_str()));
        Result = Append(Result,const_cast<char *>((std::to_string(*pArr-120)+ ".").c_str()));
        return;
    }
}
 
 
int decoder::CalculateLongSID(int& size) {
  int length = 1, value = 0, SID = 0;
  for (;; ++pArr) {
    if (!CHECKBIT(*pArr, 7)) {
      ++length;
      *pArr &= 127;
      value |= *pArr;
      break;
    }
    else
    {
      ++length;
      *pArr &= 127;
      value |= *pArr;
      value = value << 8;
    }
  }
  for (int i = 0; i < length*8-1; ++i) {
    if(CHECKBIT(value,i)){
        SETBIT(SID,i-i/8);
    }
  }
  size += length-2;
  return SID;
 
}
 
 
void decoder::CalculateIdentifier(int len){
    CalculateIdentifierFirstByte();
    for(int i = 0; i<len && ++pArr ; ++i){
        if(*pArr == -1 || *(pArr+1) == -1)
            throw "CalculateIndentifier error";
        if(!CHECKBIT(*pArr,7)){ //if decimal number consists of only one byte
            Result = Append(Result,const_cast<char *>((std::to_string(*pArr) + ".").c_str()));
        }else //if bit 7 is set it means that length of decimal number in bytes is bigger than one byte
        {
            Result = Append(Result,const_cast<char *>((std::to_string(CalculateLongSID(i)) + ".").c_str()));
        }
    }
}
 
 
char * decoder::IntToHexChar(int number){
    char * hex = new char[3]{};
    int num = number/16;
    for(int i = 0;i < 2;++i)
    switch (num)
    {
    case 15:
        hex[i] = 'F';
        num = number%16;
        break;
    case 14:
        hex[i] = 'E';
        num = number%16;
        break;
    case 13:
        hex[i] = 'D';
        num = number%16;
        break;
    case 12:
        hex[i] = 'C';
        num = number%16;
        break;
    case 11:
        hex[i] = 'B';
        num = number%16;
        break;
    case 10:
        hex[i] = 'A';
        num = number%16;
        break;
    case 9:
        hex[i] = '9';
        num = number%16;
        break;
    case 8:
        hex[i] = '8';
        num = number%16;
        break;
    case 7:
        hex[i] = '7';
        num = number%16;
        break;
    case 6:
        hex[i] = '6';
        num = number%16;
        break;
    case 5:
        hex[i] = '5';
        num = number%16;
        break;
    case 4:
        hex[i] = '4';
        num = number%16;
        break;
    case 3:
        hex[i] = '3';
        num = number%16;
        break;
    case 2:
        hex[i] = '2';
        num = number%16;
        break;
    case 1:
        hex[i] = '1';
        num = number%16;
        break;
    case 0:
        hex[i] = '0';
        num = number%16;
        break;
    default:
        break;
    }
    return hex;
}
 
 
void decoder::AppendOctetString(int length){
     for(int i = 0; i < length && ++pArr;++i){
         char * p = IntToHexChar(*pArr);
         Result = Append(Result,p);
         delete[] p;
     }
}
 
 
void decoder::OctetStringHandler(){
    if(!CHECKBIT(*++pArr,7)){
        if(*pArr == -1 )
            throw "IntegerHandler error";
 
        Result = Append(Result,const_cast<char *>(" Octet String : { "));
        AppendOctetString(ParseLength(*pArr));
        Result = Append(Result,const_cast<char *>("}"));
    }
    ++pArr;
}
 
 
void decoder::ObjectIdentifierHandler(){
    Result = Append(Result,const_cast<char *>(" OBJECT INDENTIFIED WITH VALUE: { "));
    if(!CHECKBIT(*++pArr,7)){ //if length in one byte
 
        if(*pArr == -1 )
            throw "IntegerHandler error";
 
        CalculateIdentifier(*pArr-1);
    }
    else //behaviour not described
    {
        CalculateIdentifierFirstByte();
        CalculateIdentifier(ParseLength(*pArr));
    }
    ++pArr;
}
 
 
void decoder::IntegerHandler(){
    if(!CHECKBIT(*++pArr,7)){
 
        if(*pArr == -1 )
            throw "IntegerHandler error";
 
        Result = Append(Result,const_cast<char *>(" INTEGER WITH VALUE: { "));
        Result = Append(Result, const_cast<char *>((std::to_string(CalculateBytes(ParseLength(*pArr)))+ " }").c_str()));
    }
    else
    {
        Result = Append(Result,const_cast<char *>(" INTEGER WITH VALUE: { "));
        Result = Append(Result, const_cast<char *>((std::to_string(CalculateBytes(CalculateBytes(ParseLength(*pArr))))+ " }").c_str()));
    }
    ++pArr;
}
 
 
void decoder::SequenceHandler(){
    if(!CHECKBIT(*++pArr,7)){
 
            if(*pArr == -1 )
                throw "SequenceHandler error";
 
            Result = Append(Result,const_cast<char *>(" SEQUENCE WITH LENGTH: "));
            Result = Append(Result, const_cast<char *>((std::to_string(*pArr) + "{ \n\t").c_str()));
      }
    else
    {
        Result = Append(Result,const_cast<char *>(" SEQUENCE WITH LENGTH: "));
        Result = Append(Result, const_cast<char *>((std::to_string(CalculateBytes(ParseLength(*pArr)))+ "\n\t").c_str()));
    }
    ++pArr;
}
 
 
void decoder::decode64(const char * Text,char * cipherT, char * Other){
    
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
28.01.2020, 22:43
Ответы с готовыми решениями:

Советы по ускорению работы кода + оценка самого кода
Вчера вечером сел написать 3 консольные программки для работы с шаблонами размножения текста: 1.Выборка групп синонимов(создание словаря)...

Оценка кода
Добрый день! Есть задание в ВУЗе: Я сделал следующий код: #include &lt;iostream&gt; #include &lt;conio.h&gt; int...

Оценка кода
Суть задачи описал вначале кода, хотелось бы услышать, что можно было сделать лучше, где можно было бы написать/описать...

123
Just Do It!
 Аватар для XLAT
4217 / 2677 / 656
Регистрация: 23.09.2014
Сообщений: 9,128
Записей в блоге: 3
09.02.2020, 04:06
Студворк — интернет-сервис помощи студентам
DrOffset,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void* operator new(size_t size)
        {   std::cerr << "123456\n";
            void* p;
            //try
            {   //p = malloc(size);
            }
            //catch (const std::bad_array_new_length&)
            {   //std::cerr << "bad_array_new_lenght3\n";
                //std::cin.get();
            }
            //catch (const std::bad_alloc&)
            {   std::cout << "bad_array_new_lenght4\n";
                //std::cin.get();
            }
            
            return p;
        }
(ахтунг: комменты в коде не отражают суть станцованных этой перегрузкой танцев.)

вот такую хрень я поставил, но поведение не смог распарсить,
надо со свежими москами на неё заходить
массивы из класса одномерные все сделал для удобства
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,822
09.02.2020, 04:20
Собственно <исключения>, как стратегия обработки исключительных ситуаций, потому и появилась, что необходим был механизм разгрузки бизнес-логики от проверок не своего уровня. Если ситуация на слишком низком уровне абстракции вынуждает писать проверки (я подчеркиваю проверки, а не обработку) для нее на слишком высоком, то это может сказаться нелучшим образом на общей структуре проекта. Иногда на высоких уровнях просто не хватает данных, чтобы предпроверить какие-то состояния. Если же проверять на низких уровнях, то высокому уровню надо все равно как-то сообщить о полученном исключительном состоянии, что вынуждает написать еще одну проверку этого на высоком уровне. Да, это естественно не всегда критично, поэтому есть куча проектов без исключений.

Добавлено через 13 минут
Да, я еще хотел бы добавить. Что предлагаю отталкиваться от ситуации, что исключения нам даны. И решаем мы задачу в контексте возможности присутствия исключений в проекте.
Если начать развивать диалог в сторону централизованного отказа от исключений в С++ в любых проектах, то через некоторое время выяснится (возможно страниц через 50 в этой теме), что целесообразно было бы вообще отказаться от С++, а перейти на какой-либо язык функционального программирования, как более чистый концептуально. А там таких проблем нет вообще. Поэтому предлагаю сэкономить всем время и даже не начинать
В конце концов, RAII имеет значительную свою силу именно в контексте присутствия исключений. Без них, его полезность сильно уменьшилась бы (именно поэтому в С нет RAII, ведь там нет и исключений). Вот слова Страуструпа:
First of all there are things that just can't be done right without exceptions. Consider an error detected in a constructor; how do you report the error? You throw an exception. That's the basis of RAII (Resource Acquisition Is Initialization), which it the basis of some of the most effective modern C++ design techniques: A constructor's job is to establish the invariant for the class (create the environment in which the members function are to run) and that often requires the acquisition of resources, such as memory, locks, files, sockets, etc.
2
Just Do It!
 Аватар для XLAT
4217 / 2677 / 656
Регистрация: 23.09.2014
Сообщений: 9,128
Записей в блоге: 3
09.02.2020, 04:54
Цитата Сообщение от DrOffset Посмотреть сообщение
Если начать развивать диалог в сторону централизованного отказа от исключений в С++
нет.
самая самая моя первая мысль была о том,
чтобы отказаться от new в списке инициализации,
но менять условие задачи это не айс,
и я сразу от этого отказался.
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
09.02.2020, 12:07  [ТС]
DrOffset, так std::bad_alloc выкидывается если malloc возвращает nullptr но при этом длина больше 0?Не могу что-то найти по этому поводу. Просто что-то делать сейчас не могу тк не имею доступа к компьютеру,но задача интересная но я не стал бы использовать контейнеры точно

Добавлено через 36 секунд
XLAT, так если там будет массив типа int (пример) то Ваш оператор же не сработает

Добавлено через 23 минуты
DrOffset, насчёт смарт поинтеров я не знаю как их применять с массива и, разве есть способ различать указывает указатель на массив данных или на один кусок переменной
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
09.02.2020, 12:51
Цитата Сообщение от DrOffset Посмотреть сообщение
Почему бы не поговорить на примере bad_alloc о всех остальных исключениях?
я правильно тебя понял:
ты предолжил пофиксить код, который не кидает ничего, кроме std::bad_alloc,
специально для того, что бы поболтать о каких то других,
не относящихся к твоему примеру экспшенах?

Цитата Сообщение от DrOffset Посмотреть сообщение
То, что есть ситуации, когда bad_alloc можно не обрабатывать как-то меняет дело?
конечно меняет.
если на bad_alloc можно забить,
и ничего другого оттуда вылететь не может,
то можно вообще никак не фиксить.
0
Just Do It!
 Аватар для XLAT
4217 / 2677 / 656
Регистрация: 23.09.2014
Сообщений: 9,128
Записей в блоге: 3
09.02.2020, 13:13
Цитата Сообщение от ReYalp Посмотреть сообщение
Ваш оператор же не сработает
не, не.
с чего вы решили что я на этом остановился?

Тогда так:
Цитата Сообщение от XLAT Посмотреть сообщение
(ахтунг: сей сорс-дамп не отражает суть станцованных этой перегрузкой танцев.)
---
Цитата Сообщение от ReYalp Посмотреть сообщение
насчёт смарт поинтеров
ага чёт этих понтов нигде не видно
но тогда подождемс ...

моя текущая мысль:
задача эта не может быть решена без какой-либо реорганизации этого класса.
а если это так, тогда я бы запретил себе делать ньюки в списке инициализации,
что и явилось бы решением.

Добавлено через 5 минут
и как продолжение:
один указатель - один класс.
тогда процесс исправления можно будет сделать универсально .
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,822
09.02.2020, 13:50
Цитата Сообщение от XLAT Посмотреть сообщение
тогда я бы запретил себе делать ньюки в списке инициализации,
что и явилось бы решением.
Можете показать как. Я думаю ReYalp было бы интересно.

Цитата Сообщение от XLAT Посмотреть сообщение
и как продолжение:
один указатель - один класс.
Покажите. Я же дал пример, он достаточно простой, чтобы быстро его поменять как вы считаете нужным.

Цитата Сообщение от hoggy Посмотреть сообщение
я правильно тебя понял:
ты предолжил пофиксить код, который не кидает ничего, кроме std::bad_alloc,
специально для того, что бы поболтать о каких то других,
не относящихся к твоему примеру экспшенах?
Ну в целом да, потому что с точки зрения концепции - bad_alloc ничем не отличается от других исключений. RAII работает с ним точно так же.

Цитата Сообщение от hoggy Посмотреть сообщение
конечно меняет.
если на bad_alloc можно забить,
и ничего другого оттуда вылететь не может,
то можно вообще никак не фиксить.
Вообще я прошу пофиксить код, с учетом наличия в нем исключений, а не сам по себе bad_alloc. Если ты обратил внимание, я не говорил, что в коде будет bad_alloc.
Я только говорил, что в нем потенциально возможно исключение.
Цитата Сообщение от DrOffset Посмотреть сообщение
Что будет с памятью по m_xseq, если во время второго в списке выделения памяти (инициализация m_yseq) будет брошено исключение?
Как бы вы это пофиксили?
Добавлено через 57 секунд
Цитата Сообщение от ReYalp Посмотреть сообщение
насчёт смарт поинтеров я не знаю как их применять с массива
C++
1
2
size_t n = 10;
std::unique_ptr<int[]> p(new int[n]);
0
Just Do It!
 Аватар для XLAT
4217 / 2677 / 656
Регистрация: 23.09.2014
Сообщений: 9,128
Записей в блоге: 3
09.02.2020, 13:57
Цитата Сообщение от DrOffset Посмотреть сообщение
Можете показать как
телепортируют ли меня на Альф-Центарва, если я не провалю экзамен???


Добавлено через 1 минуту
Цитата Сообщение от DrOffset Посмотреть сообщение
unique_ptr
как потом убедиться, что память возвращена?
с униками я поэксперементировал и меня это волнует.
смотреть в диспетчер или есть ещё способы?
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
09.02.2020, 14:03
Цитата Сообщение от XLAT Посмотреть сообщение
Можете показать как
первое что пришло в голову
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
class Seq2d_base
{
protected:
 
    int ** m_xseq;
 
    size_t m_xs;
 
public:
    Seq2d_base(size_t x) :m_xseq(new int *[x]), m_xs(x) {}
 
    ~Seq2d_base()
    {
        delete[] m_xseq;
    }
};
 
class Seq2d : protected Seq2d_base
{
public:
    Seq2d(size_t x, size_t y)
        : Seq2d_base(x), m_yseq(new int[x * y]{}), m_ys(y)
    {
        for (size_t i = 0; i < x; ++i)
        {
            m_xseq[i] = &m_yseq[i * y];
        }
    }
    ~Seq2d()
    {
        delete[] m_yseq;
    }
    //..... other methods
 
    int operator()(size_t i, size_t j) const
    {
        return m_xseq[i][j];
    }
    int & operator()(size_t i, size_t j)
    {
        return m_xseq[i][j];
    }
 
    size_t xsize() const
    {
        return m_xs;
    }
    size_t ysize() const
    {
        return m_ys;
    }
 
private:
 
    int  * m_yseq;
 
    size_t m_ys;
};
1
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.02.2020, 14:09
Цитата Сообщение от XLAT Посмотреть сообщение
как потом убедиться, что память возвращена?
Как обычно исключения ловить? Использовать версию new без исключений и проверять !=nullptr ?

Только смысл использовать смарты с массивами? Кода есть vector и array.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,822
09.02.2020, 14:16
Цитата Сообщение от ReYalp Посмотреть сообщение
так std::bad_alloc выкидывается если malloc возвращает nullptr но при этом длина больше 0?Не могу что-то найти по этому поводу.
Вы можете поискать потом (в книге Липпмана, которую вы сейчас читаете это раздел 19.1), сейчас это не особо важно.
То, что в этой теме акцентировали такое внимание на bad_alloc, идет в некоторый разрез с моей задумкой. Я писал об этом выше - напишу еще раз. bad_alloc не играет здесь роли, само по себе наличие исключения - играет, а то, что это конкретно bad_alloc - нет.

Добавлено через 2 минуты
Цитата Сообщение от Avazart Посмотреть сообщение
Только смысл использовать смарты с массивами? Кода есть vector и array.
Цитата Сообщение от DrOffset Посмотреть сообщение
Только давайте абстрагируемся о того, что там выделяются массивы целых.
Думайте о них, как о двух ресурсах.
...

Добавлено через 1 минуту
Цитата Сообщение от zayats80888 Посмотреть сообщение
первое что пришло в голову
Пойдет.
Оставим пока в копилке.

Цитата Сообщение от XLAT Посмотреть сообщение
елепортируют ли меня на Альф-Центарва, если я не провалю экзамен???
Тут нет никакого экзамена. Вы о чем?

Добавлено через 1 минуту
Цитата Сообщение от XLAT Посмотреть сообщение
как потом убедиться, что память возвращена?
с униками я поэксперементировал и меня это волнует.
Я правильно понял, что вы хотели бы логировать процесс освобождения памяти?
Как вы делали это раньше, без "уников"?
0
Just Do It!
 Аватар для XLAT
4217 / 2677 / 656
Регистрация: 23.09.2014
Сообщений: 9,128
Записей в блоге: 3
09.02.2020, 14:18
Цитата Сообщение от Avazart Посмотреть сообщение
Только смысл использовать смарты с массивами?
бросьте,
мы же не в гугле работаем, чтобы рассуждать также как они там.

Цитата Сообщение от zayats80888 Посмотреть сообщение
первое что пришло в голову
вот вот я как раз об этом,
вы то куда торопитесь вперёд меня,
доктор же у меня экзамен принимает.

0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.02.2020, 14:23
Цитата Сообщение от XLAT Посмотреть сообщение
бросьте,
мы же не в гугле работаем, чтобы рассуждать также как они там.
Что бы думать и рассуждать нужно в гугле обязательно работать?
Но подумав чуть больше: конечно да наверное все же в таких случаях как двумерный массив проще использовать просто массивы.
0
Just Do It!
 Аватар для XLAT
4217 / 2677 / 656
Регистрация: 23.09.2014
Сообщений: 9,128
Записей в блоге: 3
09.02.2020, 14:29
Цитата Сообщение от Avazart Посмотреть сообщение
Что бы думать и рассуждать нужно в гугле обязательно работать?
вы разве не заметили, что то был комплимент вам?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
09.02.2020, 14:46
Цитата Сообщение от DrOffset Посмотреть сообщение
Ну в целом да, потому что с точки зрения концепции - bad_alloc ничем не отличается от других исключений.
в целом дибильный у тебя получился пример.
ты понимаешь почему?

Цитата Сообщение от DrOffset Посмотреть сообщение
Вообще я прошу пофиксить код, с учетом наличия в нем исключений, а не сам по себе bad_alloc. Если ты обратил внимание, я не говорил, что в коде будет bad_alloc.
Я только говорил, что в нем потенциально возможно исключение.
если ты обратил внимание, ты привел конкретный код,
который может кинуть только bad_alloc.

рассматривать что-то ещё, помимо bad_alloc, в ситуации,
когда ничего кроме bad_alloc быть не может - это идиотизм

ты не находишь?
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.02.2020, 14:52
Цитата Сообщение от hoggy Посмотреть сообщение
рассматривать что-то ещё, помимо bad_alloc, в ситуации,
когда ничего кроме bad_alloc быть не может - это идиотизм
Да но в реальном коде всегда могут быть другие исключения приводящие к утечкам?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,822
09.02.2020, 14:54
Цитата Сообщение от hoggy Посмотреть сообщение
в целом дибильный у тебя получился пример.
Другого я от тебя и не ждал

Цитата Сообщение от hoggy Посмотреть сообщение
если ты обратил внимание, ты привел конкретный код,
который может кинуть только bad_alloc.
рассматривать что-то ещё, помимо bad_alloc, в ситуации,
когда ничего кроме bad_alloc быть не может - это идиотизм
ты не находишь?
Не рассматривай что-то еще. Рассматривай, пожалуйста, только bad_alloc, я для этого конкретный код и дал.
Но ты сейчас скажешь, что если рассматривать только bad_alloc, то ничего делать не нужно, потому что bad_alloc никто не обрабатывает?
Ладно, я помогу тебе: считай, что условия проекта такие, что мы не можем оставлять код без освобождения памяти в случае bad_alloc. Да, программа может упасть, обрабатывать bad_alloc не надо, но перед этим в ней должны вызываться все возможные деструкторы и освободиться вся возможная память.
0
Just Do It!
 Аватар для XLAT
4217 / 2677 / 656
Регистрация: 23.09.2014
Сообщений: 9,128
Записей в блоге: 3
09.02.2020, 14:57
DrOffset,
вот,
можете пальчиком даже потрогать.
(сорри я кое-что выкинул для рейта, если желаете можете вернуть на место)
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
#include <iostream>
#include <memory>
 
///----------------------------------------------------------------------------:
struct M
{   public:
        M(size_t x) : n(x)
        {   std::cout << "M\n";
            try
            {   p = new int[x];
            }
            catch (const std::bad_alloc&)
            {   std::cout << "bad_array_new_length\n";
                std::cout << "Pleese PRESS key...\n";
                std::cin.get();
            }
        }
        ~M()
        {   if(p != NULL) delete[] p;
            std::cout << "delete\n";
        }
        size_t n;
        int*   p;
};
 
///----------------------------------------------------------------------------:
class Seq2d
{
public:
    Seq2d(size_t x, size_t y)
        : m_xseq(x), m_yseq(y), m_xs(x), m_ys(y)
    { 
        std::cout << "Seq2d()\n";
    }
    ~Seq2d()
    {   std::cout << "~Seq2d()\n";
    }
    //..... other methods
    
    size_t xsize() const
    {   return m_xseq.n;
    }
    size_t ysize() const
    {   return m_xseq.n;
    }
    
private:
    M m_xseq; 
    M m_yseq;
    
    size_t m_xs;
    size_t m_ys;
};
 
///----------------------------------------------------------------------------:
int main()
{   Seq2d seq2d(5000, 7000000000);
}
ну и как?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,822
09.02.2020, 15:04
Как я уже говорил, достаточно трудно дать пример, который устроил бы всех.
1) Если дать код с абстрактными FooBar - обязательно кто-то скажет, что пример ничего не иллюстрирует, потому что нет предметной области, значит он надуман, значит в реальности такого не бывает
2) Если дать код из реальной предметной области, он вероятнее всего будет вообще никому не понятен, потому что вырван из контекста.
3) Этот пункт про такой код, который я дал выше.



Цитата Сообщение от XLAT Посмотреть сообщение
ну и как?
Хороший пример. Обрабатывать bad_alloc правда было не обязательно, т.к. это и не требовалось.
А так пример очень показательный. От этого примера до смартпойнтеров - рукой подать.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
09.02.2020, 15:31
Цитата Сообщение от DrOffset Посмотреть сообщение
Но ты сейчас скажешь, что если рассматривать только bad_alloc, то ничего делать не нужно, потому что bad_alloc никто не обрабатывает?
разумеется.

причем я дал это понять с самого начала нашего диалога.
и ты сразу это понял.

только я никогда не утверждал: "никто не обрабатывает".
я уточнил деталь: а нафига его фиксить?

Цитата Сообщение от DrOffset Посмотреть сообщение
Ладно, я помогу тебе:
вот не надо делать мне одолжений.
ты не мне, ты себе помогаешь.

сначала привел дураццкий пример,
и вот только сейчас начал по человечески его подправлять.

Цитата Сообщение от DrOffset Посмотреть сообщение
мы не можем оставлять код без освобождения памяти в случае bad_alloc. Да, программа может упасть, обрабатывать bad_alloc не надо, но перед этим в ней должны вызываться все возможные деструкторы и освободиться вся возможная память.
ну и нафига это нужно?

я бы понял, если бы у тебя там какие то ресурсы системы захватывались.
но у тебя - массив интов.

пусть падает.

Кликните здесь для просмотра всего текста
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
#include <stdexcept>
#include <iostream>
#include <cstdlib>
 
struct Seq2d
{
    Seq2d& operator=(const Seq2d&) = delete;
    Seq2d(const Seq2d&)            = delete;
    
    Seq2d(size_t x, size_t y)
        : m_xseq(new(std::nothrow) int *[x])
        , m_yseq(new(std::nothrow) int[x * y]{})
    { 
        if(!m_xseq || !m_yseq)            
            throw std::bad_alloc();
    }
    ~Seq2d()
    {
         delete[] m_xseq;
         delete[] m_yseq;
    }
    
    int ** m_xseq; 
    int  * m_yseq;
};
 
int main()
{
    try
    {
        Seq2d(100, 500);
    }
    catch(const std::exception& e)
    {
        std::cerr << e.what();
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}


Кликните здесь для просмотра всего текста
вот так должен был выглядить твой синтетический пример:
всмысле не int, а SomeType

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
#include <stdexcept>
#include <iostream>
#include <cstdlib>
#include <string>
 
bool need_throw;
 
struct value
{
    value(const std::string& n) : name(n)
    {
        std::cout << "value: " << name << '\n';
        if(need_throw)
            throw std::runtime_error("simulate error: " + name);
        need_throw = true;
    }
        
    ~value()
    {
        std::cout << "~value: " << name << '\n';
    }
    
    std::string name;
};
 
struct sample
{
    sample(const sample&)            = delete;
    sample& operator=(const sample&) = delete;
    
    sample() : first(), second()
    {
        std::cout <<"body of sample`s constructor\n";
        try
        {
            first  = new value("first" );
            second = new value("second");
        }
        catch (const std::exception& e)
        {
            delete first;
            delete second;
            throw;
        }
    }
    
    ~sample()
    {
        delete first;
        delete second;
    }
    
    value* first;
    value* second;
};
 
 
int main()
{
    try 
    {
        sample example;
    }
    catch (const std::exception& e)
    {
        std::cerr << "main: " << e.what() << std::endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.02.2020, 15:31
Помогаю со студенческими работами здесь

оценка кода
Дайте оценку моему коду (https://onlinegdb.com/r1i-i8Cqm), укажите на ошибки

Оценка стиля кода
Народ, есть предложение. Оцените мой код. Не в смысле функционала - в смысле стиля написания. Значится, вот тут есть некий код: bool...

Оценка кода динамического двумерного массива
Доброго времени суток. Прошу оценить правильность выделения и удаления памяти, а также заполнения массива. Два примера. Вот первый. В...

Список учеников имеет следующую структуру: фамилия – класс - оценка по алгебре - оценка по физике - средний балл
Задание такое Список учеников имеет следующую структуру: фамилия – класс - оценка по алгебре - оценка по физике - средний балл. При...

Оценка стиля написания кода
Здравствуйте! Я к вам пожаловал не с очередной проблемой. Код у меня рабочий. Меня интересует то, насколько стандартен мой стиль...


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

Или воспользуйтесь поиском по форуму:
100
Ответ Создать тему
Новые блоги и статьи
[golang] Алгоритм «Хак Госпера»
alhaos 17.05.2026
Алгоритм «Хак Госпера» Хак Госпера (Gosper's Hack) — алгоритм нахождения следующего по величине числа с тем же количеством установленных бит. Придуман Биллом Госпером в 1970-х, опубликован в. . .
Рисование бинарного древа до 6-го колена на js, svg.
russiannick 17.05.2026
<svg width="335" height="240" viewBox="0 0 335 240" fill="#e5e1bb"> <style> <!]> </ style> <g id="bush"> </ g> </ svg> function fn(){ let rost;/ / высота древа let xx=165,yy=210,w=256;
FSharp: interface of module
DevAlt 16.05.2026
Интерфейс модуля F# позволяет управлять доступностью членов, содержащихся в реализации модуля. По-умолчанию все члены модуля доступны: module Foo let x = 10 let boo () = printfn "boo" . . .
Хитросплетение родственных связей пантеона греческих богов.
russiannick 14.05.2026
Однооконник, позволяющий узреть и изучить отдельных героев древней Греции. <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible". . .
[golang] Угол между стрелками часов
alhaos 12.05.2026
По заданным значениям часа и минуты необходимо определить значение меньшего угла между стрелками аналогового циферблата часов. import "math" func angleClock(hour int, minutes int) float64 { . . .
Debian 13: Установка Lazarus QT5
ВитГо 09.05.2026
Эта инструкция моя компиляция инструкций volvo https:/ / www. cyberforum. ru/ blogs/ 203668/ 10753. html и его же старой инструкции по установке Lazarus с gtk2. . .
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru