Вопрос № 175733: Здравствуйте, эксперты. Что не правильно в моем коде? Программу может хранить массив из произвольного числа объектов класса. Но при попытке записать данные в класс, программа вылетает. Оператор new - НЕ подходит, т. к. количе...
Вопрос № 175733:
Здравствуйте, эксперты.
Что не правильно в моем коде?
Программу может хранить массив из произвольного числа объектов класса. Но при попытке записать данные в класс, программа вылетает.
Оператор new - НЕ подходит, т. к. количество объектов массива может быть изменено в любой момент, и следовательно, память будет постоянно "перевысвобождаться".
Отвечает Сандров Алекс, Студент :
Здравствуйте, Иванов Андрей Владимирович.
Тут сразу есть одна большая ошибка с самостоятельными alloc-ами: если в структуре есть переменные классов с конструкторами, то вызова этих конструкторов не будет! Для того и нужен new, он, кроме того что память выделяет, он делает правильную инициализацию. Он запустит конструктор класса, а конструктор запустит конструкторы своих переменных, и так далее.
Это видно, если посмотреть под дебагом
состояние users после первого realloc: у строчном указателе мусор: 0xcdcdcdcd, и при обращении в SetName, класс string воспримет это, как валидную строчку и начнёт копирование по битому адресу.
Если нужно постоянно перевыделять память, даже таким странным образом, оператор new тоже подходит, достаточно просто завести пару указателей, по одному хранить данные, по второму выделять новое пространство, потом через memcpy перегонять одно в другое (опять же, аккуратней
с указателями!), realloc делает тоже самое, только "тупо" выделяя кусок памяти без какой-либо инициализации. Alloc-ами надо пользоваться только на примитивных стуктурах данных, не требующих инициализации и только в случае, если требуется скорость (в играх, например).
В приложении привёл работающий код с закомментированными старыми строками. Использую вектор для хранения данных. Вектор позволяет резервировать память под данные (функция reserve) что избавить от постоянного её выделения. А так
же есть параметро (не помню) который отвечает за то, сколько памяти будет выделено за раз, когда память в векторе кончится(что-то я его в векторе не нашёл, но он точно был). Кроме того вектор даёт возможность простого доступа к данным через итераторы, или через оператор массива []. И не надо греть голову про память контейнера(только про память самих элементов).