Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.59/91: Рейтинг темы: голосов - 91, средняя оценка - 4.59
iFree
2 / 2 / 0
Регистрация: 11.10.2010
Сообщений: 35
#1

Измерение размера динамического массива

18.02.2011, 19:26. Просмотров 16630. Ответов 20
Метки нет (Все метки)

Как можно изменять размер динамического массива? К примеру, сначала у меня:

<имя_класса> *mas=new <имя_класса>[10];
.....
Ну и в процессе выполнения кода ВДРУГ понадобилось увеличить еще на несколько.
Как это сделать без буферной переменной?
Буферная переменная - это хорошо, если объекты занимают маленькое количество памяти.
Но мне нужно именно просто еще "довыделить" память для этого же массива.

Посоветуйте.
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.02.2011, 19:26
Ответы с готовыми решениями:

Определение размера динамического массива
Вопрос может не много глупый, но я подзабыл с. Считаю размер динамического...

Увелечение размера динамического массива
Добрый день! Итак, допустим есть массив: char *str = new char; Задача...

Изменение размера динамического массива
вводится числовой массив неизвестной длинны, каждое число заносится в...

Изменение размера динамического массива (resize)
Учусь менять размер динамического массива. Помогите разобраться, пожалуйста....

Динамическое увеличение размера динамического массива
Никак не могу понять как это исправить.. Помогите, пожалуйста, разобраться в...

20
alex_x_x
бжни
2455 / 1661 / 134
Регистрация: 14.05.2009
Сообщений: 7,162
18.02.2011, 19:35 #2
использовать std::vector<>
в данном случае, ни определить размер массива, ни увеличить его невозможно

с помощью сишных функций malloc/free можно сделать realloc и увеличить массив, но со своими танцами и размера конечно никто не вернет
0
iFree
2 / 2 / 0
Регистрация: 11.10.2010
Сообщений: 35
18.02.2011, 19:46  [ТС] #3
Цитата Сообщение от alex_x_x Посмотреть сообщение
использовать std::vector<>
в данном случае, ни определить размер массива, ни увеличить его невозможно

с помощью сишных функций malloc/free можно сделать realloc и увеличить массив, но со своими танцами и размера конечно никто не вернет
А можно подробнее о векторе? Я еще очень неопытен в программировании.
Я рассматривал вариант realloc, но мне не нравится
0
silent_1991
Эксперт С++
5009 / 3069 / 270
Регистрация: 11.11.2009
Сообщений: 7,043
Завершенные тесты: 1
18.02.2011, 19:48 #4
Лучший ответ Сообщение было отмечено как решение

Решение

Вот вполне себе без темповой переменной в её обычном понимании - второй массив служит не для временного хранения, а фактически становится постоянным массивом и происходит лишь одно копирование. Недостаток - надо передавать не только новый размер, а ещё и старый, чтобы корректно скопировать. Но всё же надо использовать именно вектор, раз на плюсах пишете.
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
#include <iostream>
 
template< typename T >
void my_realloc(T *&, size_t, size_t);
 
int main()
{
    int *arr = new int [10];
 
    for (size_t i = 0; i < 10; ++i)
        arr[i] = i;
 
    for (size_t i = 0; i < 10; ++i)
        std::cout << arr[i] << "  ";
 
    std::cout << std::endl;
 
    my_realloc(arr, 10, 15);
 
    for (size_t i = 10; i < 15; ++i)
        arr[i] = i;
 
    for (size_t i = 0; i < 15; ++i)
        std::cout << arr[i] << "  ";
    
    std::cout << std::endl;
 
    delete [] arr;
 
    return 0;
}
 
template< typename T >
void my_realloc(T *&arr, size_t size, size_t new_size)
{
    T *new_arr = new T [new_size];
    size = size < new_size ? size : new_size;
 
    for (size_t i = 0; i < size; ++i)
        new_arr[i] = arr[i];
 
    delete [] arr;
 
    arr = new_arr;
}
4
alex_x_x
бжни
2455 / 1661 / 134
Регистрация: 14.05.2009
Сообщений: 7,162
18.02.2011, 19:55 #5
iFree, std::vector и библиотека stl
http://www.cplusplus.com/reference/stl/vector/
но разбираться надо капитально, хотя и крайне полезно

silent_1991 предложил вполне рабочий способ
но можно покритиковать с точки зрения, что активная работа с динамической памятью таким образом приводит к ее фрагментированию
0
silent_1991
Эксперт С++
5009 / 3069 / 270
Регистрация: 11.11.2009
Сообщений: 7,043
Завершенные тесты: 1
18.02.2011, 20:06 #6
Цитата Сообщение от alex_x_x Посмотреть сообщение
активная работа с динамической памятью таким образом приводит к ее фрагментированию
Разумеется))) Но этот способ является, вроде бы, единственным "ручным" способом подобных действий. Или ошибаюсь?

Не по теме:

Кстати, никто не в курсе, по какому такому провидению разработчики не включили в язык оператора перевыделения памяти? За что они нас так любят?

0
alex_x_x
бжни
2455 / 1661 / 134
Регистрация: 14.05.2009
Сообщений: 7,162
18.02.2011, 20:52 #7
Цитата Сообщение от silent_1991 Посмотреть сообщение
Но этот способ является, вроде бы, единственным "ручным" способом подобных действий.
так и есть

ну вот страуструп у себя в C++ Style and Technique кивает в сторону stl

If you want to, you can of course use realloc(). However, realloc() is only guaranteed to work on arrays allocated by malloc() (and similar functions) containing objects without user-defined copy constructors. Also, please remember that contrary to naive expectations, realloc() occasionally does copy its argument array.
In C++, a better way of dealing with reallocation is to use a standard library container, such as vector, and let it grow naturally.
0
silent_1991
Эксперт С++
5009 / 3069 / 270
Регистрация: 11.11.2009
Сообщений: 7,043
Завершенные тесты: 1
18.02.2011, 21:01 #8
alex_x_x, ха. Т.е. они сознательно нас лишили вполне-таки полезной возможности перераспределения памяти (которое в некоторых случаях происходит без перемещения блока памяти, а именно с приращением при увеличении, а уж при уменьшении в большинстве случаев вообще копирования не происходит). Ну а если хочется мне велосипед изобрести? Нет, батенька, юзайте СТЛ)))
0
taras atavin
4204 / 1765 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
13.12.2012, 18:33 #9
Цитата Сообщение от alex_x_x Посмотреть сообщение
в данном случае, ни определить размер массива, ни увеличить его невозможно
Так и запишем: realloc прочно забыт.
0
alex_x_x
бжни
2455 / 1661 / 134
Регистрация: 14.05.2009
Сообщений: 7,162
13.12.2012, 18:49 #10
Цитата Сообщение от taras atavin Посмотреть сообщение
Так и запишем: realloc прочно забыт.
так и запишем: тарас умеет отвечать только на первую строку поста
0
activnaya
256 / 46 / 4
Регистрация: 24.11.2012
Сообщений: 466
13.12.2012, 19:00 #11
а что насчет того чтобы перераспределение было реализовано отдельным Сишным объектным модулем? Или к примеру собрать библиотеку с одной функцией из Си, и уже линковать с этой библиотекой?

Добавлено через 1 минуту
разве realloc принципиально лучше vector.resize()?
0
OhMyGodSoLong
~ Эврика! ~
1245 / 994 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
13.12.2012, 19:16 #12
Цитата Сообщение от activnaya Посмотреть сообщение
разве realloc принципиально лучше vector.resize()?
Дело больше в том, что realloc() может быть несовместим с operator new()

Не по теме:

Цитата Сообщение от silent_1991 Посмотреть сообщение
Кстати, никто не в курсе, по какому такому провидению разработчики не включили в язык оператора перевыделения памяти? За что они нас так любят?
Потому что до С++11 в языке не было move-семантики — однозначно работающего специализированного механизма для переноса объекта из одного места в другое. Не снятия копии и её присваивания, а именно переноса, ведь realloc() по идее должен именно переносить объект. А почему его не было — это другой вопрос. Наверное, потому что объекты в угоду совместимости с Си всё ещё считались значениями, а не объектами.

0
taras atavin
4204 / 1765 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
13.12.2012, 19:16 #13
Цитата Сообщение от activnaya Посмотреть сообщение
разве realloc принципиально лучше vector.resize()?
Какой вектор ресайз, если уже объявлен явный указатель? Сказано же:
в этой ситуации.
А realloc применим к явному, но не применим к завёрнутому в вектор.
0
activnaya
256 / 46 / 4
Регистрация: 24.11.2012
Сообщений: 466
13.12.2012, 19:38 #14
taras atavin, в этой ситуации надо писать на Си. А если кто-то создал эту ситуацию, то это его личные проблемы. stl vector был задуман как альтернатива массивам, вот его и надо было использовать, чтобы таких казусов не возникало.
~OhMyGodSoLong~, а что с этими мыслями?
Цитата Сообщение от activnaya Посмотреть сообщение
а что насчет того чтобы перераспределение было реализовано отдельным Сишным объектным модулем? Или к примеру собрать библиотеку с одной функцией из Си, и уже линковать с этой библиотекой?
0
OhMyGodSoLong
~ Эврика! ~
1245 / 994 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
13.12.2012, 19:42 #15
А зачем? Из Си++ realloc() вполне себе доступен.
0
silent_1991
Эксперт С++
5009 / 3069 / 270
Регистрация: 11.11.2009
Сообщений: 7,043
Завершенные тесты: 1
14.12.2012, 21:01 #16
Цитата Сообщение от activnaya Посмотреть сообщение
разве realloc принципиально лучше vector.resize()
Да, потому что в некоторых случаях реаллок реально расширяет выделенный кусок памяти. Ресайз же просто выделяет новый кусок память и копирует всё туда, а старую память удаляет. Итого, в плюсах нет стандартной возможности расширить выделенный ранее кусок памяти для не-POD типов (для подов всё ещё можно использовать тот же реаллок).
0
daslex
1291 / 535 / 177
Регистрация: 02.08.2011
Сообщений: 2,756
14.12.2012, 21:25 #17
Если скорость не критична, то можно копировать текущий массив в резервный, потом освобождать память от текущего и создавать массив с новой памятью, копируя в него данные из резерва и добавляя нужные значения
0
silent_1991
Эксперт С++
5009 / 3069 / 270
Регистрация: 11.11.2009
Сообщений: 7,043
Завершенные тесты: 1
14.12.2012, 21:28 #18
daslex, оверхэд. Достаточно одного выделения памяти, как я продемонстрировал выше. Или выделения с запасом (на случай поэлементного добавления в конец, чтобы не перевыделять память каждый раз для одного элемента), как сделано, например, в той же stl.
1
activnaya
256 / 46 / 4
Регистрация: 24.11.2012
Сообщений: 466
14.12.2012, 21:55 #19
Цитата Сообщение от silent_1991 Посмотреть сообщение
для подов всё ещё можно использовать тот же реаллок
в том числе и в случаях, когда память выделялась с помощью new(), а не malloc()?
0
OhMyGodSoLong
~ Эврика! ~
1245 / 994 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
14.12.2012, 22:01 #20
Цитата Сообщение от silent_1991 Посмотреть сообщение
Итого, в плюсах нет стандартной возможности расширить выделенный ранее кусок памяти для не-POD типов (для подов всё ещё можно использовать тот же реаллок).
Нет, ну вообще можно. Управлять памятью с помощью realloc() и вызывать конструкторы/деструкторы вручную. Но, опять же, работает не всегда (если realloc() таки перенесёт память, то объекты не в курсе, что их перенесли, так что всё поломается, если они хранят указатели друг на друга).

Если так уж напрягает полное копирование — связные списки в помощь. Их можно сделать достаточно быстро индексируемыми (unrolling, skip lists и т. п.)
0
14.12.2012, 22:01
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.12.2012, 22:01

Функция изменения размера динамического массива
Здравия желаю, Друзья. Застрял вот на чем: #include &lt;iostream&gt; #include...

Определение размера динамического массива строк
Здравствуйте, столкнулся с проблемой предопределения размера массива строк....

Изменение размера динамического массива объектов класса
Всех приветствую! Нужно изменить размер динамического массива, в котором я...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru