Форум программистов, компьютерный форум CyberForum.ru

Все ли хорошо в этом коде - C++

Восстановить пароль Регистрация
 
 
thechicho
0 / 0 / 0
Регистрация: 15.03.2015
Сообщений: 14
Завершенные тесты: 1
17.08.2016, 10:31     Все ли хорошо в этом коде #1
Предложите ваши варианты решения заданий
3. Все ли хорошо в этом коде?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Файл legacy.c
int values[3];
 
Файл modern.cpp
#define LEGACY_SIZE 3
extern int *values;
 
class MyBlah {...};
 
class Adapter
{
public:
    Adapter()
    {
        for (int i = 0; i < LEGACY_SIZE; ++i)
            map_[values[i]] = new MyBlah (values[i]);
    }
private:
    std::map<int, MyBlah *> map_;
};
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
hoggy
5225 / 2116 / 403
Регистрация: 15.11.2014
Сообщений: 4,800
Завершенные тесты: 1
17.08.2016, 22:24     Все ли хорошо в этом коде #2
thechicho,

1.
C++
1
int values[3]; // <--- глобальный объект инициализируется нулями
таким образом это:
C++
1
2
for (int i = 0; i < LEGACY_SIZE; ++i)
            map_[values[i]] = new MyBlah (values[i]);
тоже самое что и:

C++
1
2
for (int i = 0; i < LEGACY_SIZE; ++i)
        map_[0] = new MyBlah (0);  //<--- утечка памяти
2.
отсутствие диструктора ---> утечка памяти

3.
нарушение правила трех:
отсутствие конструкторов копии/перемещания и соответствующих операторов =
приведет к крашу при попытке освободить память.

4.
C++
1
for (int i = 0; i < LEGACY_SIZE; ++i)
счетчик цикла должен быть size_t

C++
1
for (size_t i = 0; i < LEGACY_SIZE; ++i)
dailydose
10 / 10 / 3
Регистрация: 21.07.2016
Сообщений: 152
17.08.2016, 22:31     Все ли хорошо в этом коде #3
Цитата Сообщение от hoggy Посмотреть сообщение
отсутствие диструктора ---> утечка памяти
дабы утечки не было нужно в деструкторе написать delete[] map_; ?
hoggy
5225 / 2116 / 403
Регистрация: 15.11.2014
Сообщений: 4,800
Завершенные тесты: 1
17.08.2016, 23:12     Все ли хорошо в этом коде #4
Цитата Сообщение от dailydose Посмотреть сообщение
дабы утечки не было нужно в деструкторе написать delete[] map_; ?
нужно книжки читать: "базовый курс для самых маленьких"
dailydose
10 / 10 / 3
Регистрация: 21.07.2016
Сообщений: 152
18.08.2016, 05:56     Все ли хорошо в этом коде #5
Цитата Сообщение от hoggy Посмотреть сообщение
для самых маленьких
На каждый new должнен быть свой delete, разве нет?
В языке программирования C++ оператор delete возвращает память, выделенную оператором new, обратно в кучу. Вызов delete должен происходить для каждого вызова new, чтобы избежать утечки памяти.
zss
Модератор
Эксперт С++
 Аватар для zss
5942 / 5547 / 1783
Регистрация: 18.12.2011
Сообщений: 14,164
Завершенные тесты: 1
18.08.2016, 07:43     Все ли хорошо в этом коде #6
Цитата Сообщение от thechicho Посмотреть сообщение
Файл legacy.c int values[3];
Цитата Сообщение от thechicho Посмотреть сообщение
Файл modern.cpp
#define LEGACY_SIZE 3
extern int *values;
Т.к. расширения файлов разные (с и срр), то компоновщик такой проект не соберет
avgoor
562 / 352 / 83
Регистрация: 05.12.2015
Сообщений: 1,137
18.08.2016, 11:09     Все ли хорошо в этом коде #7
Цитата Сообщение от zss Посмотреть сообщение
Т.к. расширения файлов разные (с и срр), то компоновщик такой проект не соберет
С чего бы вдруг? Компоновщик собирает исполняемый файл из объектных, в которых уже нет информации о языке в явном виде. И, если соглашения о вызовах совпадают - мешайте хоть c brainfuck-ом.
Voivoid
 Аватар для Voivoid
580 / 256 / 12
Регистрация: 31.03.2013
Сообщений: 1,283
18.08.2016, 12:28     Все ли хорошо в этом коде #8
Вроде никто не написал про различие типов переменных values

Цитата Сообщение от hoggy Посмотреть сообщение
счетчик цикла должен быть size_t
Кому должен?
hoggy
5225 / 2116 / 403
Регистрация: 15.11.2014
Сообщений: 4,800
Завершенные тесты: 1
18.08.2016, 13:30     Все ли хорошо в этом коде #9
Цитата Сообщение от Voivoid Посмотреть сообщение
Кому должен?
всему мировому сообществу в целом,
и корректно оформленной программе в частности.

ну или хотите писать грамотно - пишите size_t.
или будьте быдлокодерами.

вопрос не в том "кому ?", а вопрос в том: "почему это так?"
надеюсь объяснять причины не нужно?
zss
Модератор
Эксперт С++
 Аватар для zss
5942 / 5547 / 1783
Регистрация: 18.12.2011
Сообщений: 14,164
Завершенные тесты: 1
18.08.2016, 13:41     Все ли хорошо в этом коде #10
Цитата Сообщение от avgoor Посмотреть сообщение
С чего бы вдруг?
Проверил экспериментально на VS 2008.
Может где-то и не так. Но у автора вопроса явно было это на уме, иначе не стал бы давать разные расширения.
Voivoid
 Аватар для Voivoid
580 / 256 / 12
Регистрация: 31.03.2013
Сообщений: 1,283
18.08.2016, 13:43     Все ли хорошо в этом коде #11
Цитата Сообщение от hoggy Посмотреть сообщение
и корректно оформленной программе в частности.
Если тип счетчика цикла отличен от size_t, то программа становится некорректно оформленной? Кстати, что это вообще значит "корректно оформленная"?

Цитата Сообщение от hoggy Посмотреть сообщение
надеюсь объяснять причины не нужно?
Конечно нужно. Еще неплохо бы увязать объяснение с тем, что ключ у map'а имеет тип int и LEGACY_SIZE это тоже int
avgoor
562 / 352 / 83
Регистрация: 05.12.2015
Сообщений: 1,137
18.08.2016, 13:50     Все ли хорошо в этом коде #12
Цитата Сообщение от zss Посмотреть сообщение
Проверил экспериментально на VS 2008.
Плохо проверяли. В часности:
Цитата Сообщение от avgoor Посмотреть сообщение
если соглашения о вызовах совпадают
то есть должно быть extern "C". Плюс не int *values, а int values[LEGACY_SIZE].
Что не равносильно этому:
Цитата Сообщение от zss Посмотреть сообщение
Т.к. расширения файлов разные (с и срр), то компоновщик такой проект не соберет
hoggy
5225 / 2116 / 403
Регистрация: 15.11.2014
Сообщений: 4,800
Завершенные тесты: 1
18.08.2016, 15:28     Все ли хорошо в этом коде #13
Цитата Сообщение от Voivoid Посмотреть сообщение
Если тип счетчика цикла отличен от size_t, то программа становится некорректно оформленной?
да, если используемый тип не поддерживает диапазон значений size_t.

Цитата Сообщение от Voivoid Посмотреть сообщение
Кстати, что это вообще значит "корректно оформленная"?
корректно оформленная - корректна с точки зрения стандарта,
и гарантирует инвариант.

точное определение вы можете прочитать в стандарте:
(well-formed)

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

int - не гарантирует.

соответственно, использование int - потенциальная мина.
использование size_t - превентивно безопасно.

кроме технической стороны дела существует здравый смысл.

у вас что: индексы или размеры массивов могут быть отрицательными?
вы почему используете знаковый тип для хранения беззнаковых величин?
что за маразм?

Добавлено через 45 секунд
Цитата Сообщение от Voivoid Посмотреть сообщение
Еще неплохо бы увязать объяснение с тем, что ключ у map'а имеет тип int и LEGACY_SIZE это тоже int
потому что говнокод.
avgoor
562 / 352 / 83
Регистрация: 05.12.2015
Сообщений: 1,137
18.08.2016, 15:37     Все ли хорошо в этом коде #14
Цитата Сообщение от hoggy Посмотреть сообщение
у вас что: индексы или размеры массивов могут быть отрицательными?
вы почему используете знаковый тип для хранения беззнаковых величин?
что за маразм?
Потому, что данные не только хранятся, но и иногда обрабатываются И, если где-то отрицательные числа, таки, понадобятся - беззнаковые тоже могут превратиться в мину. + Учитывая, что в студии размер массива не может превышать 4Gb - проблемы возникнут только для массива char длиной более 2Gb. Для массивов всех других типов (если размер типа больше 1) проблем не возникнет.
Avazart
 Аватар для Avazart
6897 / 5137 / 252
Регистрация: 10.12.2010
Сообщений: 22,578
Записей в блоге: 17
18.08.2016, 15:40     Все ли хорошо в этом коде #15
Цитата Сообщение от hoggy Посмотреть сообщение
у вас что: индексы или размеры массивов могут быть отрицательными?
вы почему используете знаковый тип для хранения беззнаковых величин?
что за маразм?
Ну это интересный вопрос, std::string::find же возвращает npos который как бы -1.

Добавлено через 2 минуты
thechicho, основные в том к чему int values[3]; объявлен глобально, а не внутри класса.
Т.е. если были был массив констант тогда ...
HighPredator
 Аватар для HighPredator
5342 / 1725 / 320
Регистрация: 10.12.2010
Сообщений: 5,108
Записей в блоге: 3
18.08.2016, 15:53     Все ли хорошо в этом коде #16
Цитата Сообщение от Avazart Посмотреть сообщение
Ну это интересный вопрос, std::string::find же возвращает npos который как бы -1
И тем не менее это ему не мешает быть типа size_t. Просто так они записывают в него максимальное значение для типа.
Voivoid
 Аватар для Voivoid
580 / 256 / 12
Регистрация: 31.03.2013
Сообщений: 1,283
18.08.2016, 15:57     Все ли хорошо в этом коде #17
Цитата Сообщение от hoggy Посмотреть сообщение
вы почему используете знаковый тип для хранения беззнаковых величин?
Чтобы иметь возможность поставить assert на >= 0. Все равно довольно редко приходится оперировать большими числами
hoggy
5225 / 2116 / 403
Регистрация: 15.11.2014
Сообщений: 4,800
Завершенные тесты: 1
18.08.2016, 16:28     Все ли хорошо в этом коде #18
Цитата Сообщение от avgoor Посмотреть сообщение
если где-то отрицательные числа, таки, понадобятся - беззнаковые тоже могут превратиться в мину.
если вам нужны знаковые - используйте знаковый.
ваш кэп.

знаковые для хранения размеров/индексов понадобятся не могут.
ваш кэп.

Цитата Сообщение от avgoor Посмотреть сообщение
+ Учитывая, что в студии размер массива не может превышать 4Gb
это - монопенисуальный фактор.

корректный код не зависит от платформы.
это достигается за счет того, что код опирается на типы,
которые ему это гарантируют.

Цитата Сообщение от Avazart Посмотреть сообщение
как бы -1.
ага.
ключевое слово "как бе".
а главное ключевое слово - "npos".
вы сравниваетесь с константой.
и у вас нет ни одной причины думать,
что там под капотом (кроме любопытства).
и да, npos это - size_t(-1), а не -1

Цитата Сообщение от Voivoid Посмотреть сообщение
Чтобы иметь возможность поставить assert на >= 0.
то, чего не должно быть, не должно быть в принципе.
вам не нужно ставить такой ассерт при проверке индекса.
вам нужно ставить ассерт который контролирует вылет за пределы диапазона,
и только лишь.
Avazart
 Аватар для Avazart
6897 / 5137 / 252
Регистрация: 10.12.2010
Сообщений: 22,578
Записей в блоге: 17
18.08.2016, 16:31     Все ли хорошо в этом коде #19
Цитата Сообщение от hoggy Посмотреть сообщение
ага.
ключевое слово "как бе".
а главное ключевое слово - "npos".
вы сравниваетесь с константой.
и у вас нет ни одной причины думать,
что там под капотом (кроме любопытства).
и да, npos это - size_t(-1), а не -1
И тем не менее это условность/договоренность что npos это -1 или макс значение, константа или еще что либо.
(описанное в документации)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.08.2016, 16:34     Все ли хорошо в этом коде
Еще ссылки по теме:

C++ Что в этом коде не правильно?
C++ Как пронумеровать текст в этом коде?
C++ Как дописать цикл в этом коде?

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

Или воспользуйтесь поиском по форуму:
_Ivana
2177 / 1382 / 124
Регистрация: 01.03.2013
Сообщений: 4,120
Записей в блоге: 2
18.08.2016, 16:34     Все ли хорошо в этом коде #20
В памяти всплывает светлый образ еще одного местного С++ гуру, который что-то писал про мэйбимонады А это снова они, родимые: нет индекса, удовлетворяющего условию - значит "нет", а не -1 - вы же сами против сишного наследия и за красоту и ясность абстракций?
Yandex
Объявления
18.08.2016, 16:34     Все ли хорошо в этом коде
Ответ Создать тему
Опции темы

Текущее время: 23:24. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru