Модераторы: Daevaorn

Поиск:

Закрытая темаСоздание новой темы Создание опроса
> Динамический массив 
:(
    Опции темы
Baa
Дата 25.12.2002, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2639
Регистрация: 12.4.2002
Где: Москва

Репутация: 8
Всего: 12



Есть у нас динамический массив...
char* lpBuffer = new char [0xFF];
И он у нас заполнен чем-то (не важно чем).
Далее, нам надо его расширить...
lpBuffer = new char [0x200];
но вот беда, данные-то потерялись :(
Вопрос: можно ли как-то обойтись без временного второго массива?


--------------------
"Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande
PM ICQ   Вверх
Step
Дата 25.12.2002, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5151
Регистрация: 26.9.2002
Где: дурдом.UA

Репутация: 5
Всего: 25



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


--------------------
- Дурак учится на своих ошибках, умный на чужих.
 - умные учатся у дураков
PM MAIL ICQ   Вверх
Alex101
Дата 25.12.2002, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 891
Регистрация: 8.4.2002
Где: Москва

Репутация: нет
Всего: 10



Ежели говорить о реализации вообще (не опираясь на конкретный язык или его реализацию), то нельзя - память-то RAM, все ухищрения приведут к одному и тому же - сначала часть выделенной памяти не будет использоваться. А так - есть классы, позволяющие это реализовывать.
ЗЫ
Делал я программу под ДОС, она работала в графическом режиме, использовал текстовый буфер для хранения данных. Но это так, к слову пришлось:)


--------------------
С уважением, А. Фролов.
PM MAIL ICQ   Вверх
AntonSaburov
Дата 25.12.2002, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Штурман
****


Профиль
Группа: Модератор
Сообщений: 5658
Регистрация: 2.7.2002
Где: Санкт-Петербург

Репутация: нет
Всего: 118



Для таких случаев можно использовать STL - std::vector<char>
И никаких проблем больше нет :)
PM MAIL WWW ICQ   Вверх
Baa
Дата 25.12.2002, 21:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2639
Регистрация: 12.4.2002
Где: Москва

Репутация: 8
Всего: 12



Тош, дык можно и CArray... а мне вот хоца без излишеств (MFC, ATL и т.д.)... но как я понял, в любом случае, получается камасутра, а усложнять код не стоит...


--------------------
"Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande
PM ICQ   Вверх
Alex101
Дата 25.12.2002, 21:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 891
Регистрация: 8.4.2002
Где: Москва

Репутация: нет
Всего: 10



Цитата(Baa @ 25.12.2002, 13:03)
в любом случае, получается камасутра, а усложнять код не стоит...

Ежели приложение небольшое, то конечно.
А иначе - лучше перегрузить немного, но будет удобнее работать и за отладкой меньше времени просидишь.


--------------------
С уважением, А. Фролов.
PM MAIL ICQ   Вверх
AntonSaburov
Дата 25.12.2002, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Штурман
****


Профиль
Группа: Модератор
Сообщений: 5658
Регистрация: 2.7.2002
Где: Санкт-Петербург

Репутация: нет
Всего: 118



Цитата
Тош, дык можно и CArray... а мне вот хоца без излишеств (MFC, ATL и т.д.)... но как я понял, в любом случае, получается камасутра, а усложнять код не стоит...


STL - это уже стандарт, который есть практически на всех сишных компиляторах. Так что вполне нормально его использовать. Тем более если проект достаточно большой, то смысл изобретать велосипед.
PM MAIL WWW ICQ   Вверх
Baa
Дата 25.12.2002, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2639
Регистрация: 12.4.2002
Где: Москва

Репутация: 8
Всего: 12



Дык проект небольшой :) если б был большой, то я и не задался бы таким вопросом... просто иногда охото извращений ;-)


--------------------
"Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande
PM ICQ   Вверх
dim
Дата 25.12.2002, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 106
Регистрация: 24.12.2002

Репутация: нет
Всего: нет



Ну можно еще написать класс массива, в котором к примеру, перегрузить операторы new и delete. Оператор new перегрузить таким образом, что если он вызывается первый раз, то вызывать HeapAlloc, все последующие разы вызываем HeapReAlloc. Затраты конечно же будут, но в kernel mode менее ощутимо чем в user mode. К тому же можно интеллектуально использовать флаг HEAP_REALLOC_IN_PLACE_ONLY. Первый раз HeapReAlloc вызываем с этим флагом (т.е. пытаемся увеличить размер не перенося содержимое), если не вышло то вызываем HeapReAlloc уже без этого флага.
--------------------
that's all
PM MAIL   Вверх
suborg
Дата 26.12.2002, 03:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 190
Регистрация: 29.4.2002
Где: Москва

Репутация: нет
Всего: нет



Точно нельзя потому что массив в данном случае - непрерывная область памяти, но система работы кучей умеет выделять память не только из хвоста кучи, но и из дырок при фрагментации памяти в процессе работы программы, таким образом ты никогда не застрахован от того, что вслед за твоим массивом идут другие данные, следовательно по тому же адресу выделить массив другого размера нельзя, значит придется делать новый массив.
PM MAIL WWW ICQ   Вверх
dim
Дата 26.12.2002, 03:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 106
Регистрация: 24.12.2002

Репутация: нет
Всего: нет



Да, но в том случае если за массивом дырка переноса не будет, т.е при перевыделении есть значительная вероятность что переноса не будет, тогда как при простом ремейке перенос будет всегда.
--------------------
that's all
PM MAIL   Вверх
Fantasist
Дата 26.12.2002, 07:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



dim, правильно сказал. Даже если ты хочешь самы простой массив - все равно его лучше обернуть в класс. Идея по реализации, правда, была предложенна весьма геморная. :) Гораздо проще определить методы alloc и realloc в которых выполнять все необходимые действия. В самом простом варианте:

Код

template<typename T>
class Array
{
private:
 T* mData;
public:
 Array() mData(0) {};
 Array(size_t len) mData(new T[len]) {};
 ~Array() {delete[] mData;};
 
 void alloc(size_t len) {delete mData; mData=new T[len];};
 void realloc(size_t len) {....};

 operator T*() {return mData;};
}


Реализация realloc зависит от задачи(как, на самом деле, и реализация аллокации). Если это будет использоваться только с простыми типами, то подойдет почти любой способ - и с вин API и с malloc/realloc и также new/delete/memcpy.  Если будут использоваться массивы классов, то надо вызывать конструкторы и деструкторы, а при реаллокации еще и поэлементно копировать (с помощью operator=), но для этого надо знать сколько копировать, а значит либо хранить длинну внутри класса, либо....


--------------------
Волны гасят ветер...
PM MAIL   Вверх
Nastya
Дата 26.12.2002, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 27.3.2002
Где: Мариуполь

Репутация: 5
Всего: 44



Есть два варианта:
1. Прользоваться new, но перед повторным выдлением памяти копировать массив во временный, удалять его, создавать новы и копировать наместо.
2. Пользоваться функциями malloc и  realloc из библионтеки stdlib


--------------------
Что бы понять рекурсию, надо понять рекурсию

"Профессионал - это человек сделавший все возможные ошибки в очень узкой области". Н.Бор
PM MAIL   Вверх
Baa
Дата 27.12.2002, 00:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2639
Регистрация: 12.4.2002
Где: Москва

Репутация: 8
Всего: 12



Цитата(Nastya @ 26.12.2002, 14:54)
Есть два варианта:
1. Прользоваться new, но перед повторным выдлением памяти копировать массив во временный, удалять его, создавать новы и копировать наместо.
2. Пользоваться функциями malloc и  realloc из библионтеки stdlib

Насть, дык я ж грю, что эти варианты не подходят...
мне-то было интересно, можно ли с помощью new... а другие варианты я и сам знаю :)
з.ы. сам делаю через временный массив (если токо с winapi).


--------------------
"Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande
PM ICQ   Вверх
dim
Дата 27.12.2002, 04:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 106
Регистрация: 24.12.2002

Репутация: нет
Всего: нет



Цитата

Идея по реализации, правда, была предложенна весьма геморная

Один раз реализовать, а потом можно использовать. Вот пример:
Код

template<class T, int number>
class CVector
{
protected:
static T *data[number];
static HANDLE heap;
static int count;
public:
CVector() {};
~CVector() {};
void *operator new [] (unsigned int cb)
{
if  (data[count])
data[count] = (T *)HeapReAlloc(heap, HEAP_ZERO_MEMORY, data[count], cb * sizeof(T));
else
data[count] = (T *)HeapAlloc(heap, 0, cb * sizeof(T));
T *p = data[count];
return p;
}
void operator delete(void *)
{
if  (data[count])
HeapFree(heap, 0, data[count]);
}
static void Initialize() {
heap = HeapCreate(0, 0x2000, 0);
count = 0;
memset(data, 0, sizeof(T*) * number);
};
static void Release() { HeapDestroy(heap); };
static void SetVector(int ncount) { count = ncount; };
T& operator [](int index) { return data[count][index]; };
};

--------------------
that's all
PM MAIL   Вверх
Fantasist
Дата 27.12.2002, 05:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Ой-ой. По-моему, плохая реализация. Зачем перегружать new/delete? Зачем делать все static? Почти никакой инкапсуляции. Пользоваться таким массивом очень неудобно. Все равно приходиться вызывать new/delete плюс к этому, надо вызывать SetVector и Release. Для своих классов его опять же использовать нельзя - объекты не конструируются. А для простых типов, так лучше использовать std::valarray или сделать свою простую версию, как я предложил используя malloc/realloc/memcpy.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
dim
Дата 27.12.2002, 05:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 106
Регистрация: 24.12.2002

Репутация: нет
Всего: нет



Цитата

Зачем перегружать new/delete? Зачем делать все static?

Как раз затем, чтобы с ним было удобно работать.
Цитата

Почти никакой инкапсуляции. Пользоваться таким массивом очень неудобно. Все равно приходиться вызывать new/delete плюс к этому, надо вызывать SetVector и Release.

Демагогическое утверждение. Initialize и Release вызываются всего один раз, SetVector лишь в том случае если использются несколько массивов (т. е при правильной проектировке это вообще это не будет вызывать никаких неприятностей).
Цитата

Для своих классов его опять же использовать нельзя - объекты не конструируются. А для простых типов, так лучше использовать std::valarray или сделать свою простую версию, как я предложил используя malloc/realloc/memcpy.

Я не ставил себе задачу построить универсальный класс, рассчитаный еще и на custom типы, но очевидно что при желании его можно допилить до этого. Хотя это не существенно, поскольку для подобных задач существуют стандартные классы типа std::vector, а я предлагал решение по первоначальной постановке задачи. Что касается malloc/realloc кака по мне то это неудобно.
--------------------
that's all
PM MAIL   Вверх
Baa
Дата 27.12.2002, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2639
Регистрация: 12.4.2002
Где: Москва

Репутация: 8
Всего: 12



Хорошо, с этим все понятно... можно разработать свой класс/шаблон или пользоваться уже существующими.
А как это реализовано в CArray?
з.ы. в исходники пока не лез.


--------------------
"Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande
PM ICQ   Вверх
AntonSaburov
Дата 27.12.2002, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Штурман
****


Профиль
Группа: Модератор
Сообщений: 5658
Регистрация: 2.7.2002
Где: Санкт-Петербург

Репутация: нет
Всего: 118



Цитата
А как это реализовано в CArray?
з.ы. в исходники пока не лез.


А чего там лезть - тот же template, что-то типа Vector. Нормальное использование STL. Дольше обсуждаем, чем делаем :)
PM MAIL WWW ICQ   Вверх
dim
Дата 27.12.2002, 21:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 106
Регистрация: 24.12.2002

Репутация: нет
Всего: нет



Цитата

А как это реализовано в CArray?
з.ы. в исходники пока не лез.

А вот так как раз реализовано обычным копированием (переносим старые данные, аллоцируем новый размер и переносим все обратно).
--------------------
that's all
PM MAIL   Вверх
Baa
Дата 28.12.2002, 01:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2639
Регистрация: 12.4.2002
Где: Москва

Репутация: 8
Всего: 12



Цитата(AntonSaburov @ 27.12.2002, 13:31)
Дольше обсуждаем, чем делаем :)

Все уже дааавно сделано ;-) просто софистику люблю ;-)


--------------------
"Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande
PM ICQ   Вверх
Fantasist
Дата 28.12.2002, 05:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата
Как раз затем, чтобы с ним было удобно работать.

Демагогическое утверждение.


Прювет. Люди придумывают столько разных инкапсуляторов, для того чтобы НЕ вызывать самим new/delete (при исключениях это особенно удобно), а вы в нагрузку предлагаете еще и два метода вызывать. Если мне захочется пользоваться вашим классом, мне придется писать еще обертку к нему.

Цитата
SetVector лишь в том случае если использются несколько массивов


Вы что, хотите сказать, что в программе обычно используется всего лишь ОДИН массив?

Цитата
(т. е при правильной проектировке это вообще это не будет вызывать никаких неприятностей).


При правильной проектировке, такого класса, как у вас, не будет.

Цитата
а я предлагал решение по первоначальной постановке задачи


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

Цитата
(переносим старые данные, аллоцируем новый размер и переносим все обратно).


Не думаю, что так много. Скорее всего: аллоцируем новую память, копируем в нее старые данные (и конструируем новые элементы). Не зачем данные туда и обратно таскать.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
dim
Дата 30.12.2002, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 106
Регистрация: 24.12.2002

Репутация: нет
Всего: нет



Цитата

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

У меня такое ощущение, что ты вообще не читал о чем идет речь в топике. Кстати я и не заставляю пользоваться тебя своим классом. Мне вообщем-то такие извращения на фиг не нужны и я сторонник использования старого доброго того что уже сделано и проверено, но был вопрос и я постарался дать на него ответ, но не спорить о том как лучше организовывать классы враперы. Это вообщем попахивает офтопиком.
--------------------
that's all
PM MAIL   Вверх
Vaulter
Дата 31.12.2002, 05:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1724
Регистрация: 30.12.2002
Где: бункер

Репутация: 2
Всего: 22



Baa на самом деле STL сделает так, что любые твои ручные ухищрения окажутся в конечном итоге больше, медленее и неудобнее.


--------------------
PM MAIL WWW ICQ   Вверх
Fantasist
Дата 31.12.2002, 06:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата
Baa на самом деле STL сделает так, что любые твои ручные ухищрения окажутся в конечном итоге больше, медленее и неудобнее.


Хе-хе. :) Могу найти ссылку на конференцию comp.lang.cpp, где обсуждался подобный вопрос. STL универсальна, а потому не может обеспечить наибольшей эффективности во всех случаях.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
Fantasist
Дата 31.12.2002, 06:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата(dim @ 30.12.2002, 13:12)
У меня такое ощущение, что ты вообще не читал о чем идет речь в топике. Кстати я и не заставляю пользоваться тебя своим классом. Мне вообщем-то такие извращения на фиг не нужны и я сторонник использования старого доброго того что уже сделано и проверено, но был вопрос и я постарался дать на него ответ, но не спорить о том как лучше организовывать классы враперы. Это вообщем попахивает офтопиком.

Ок.  :)


--------------------
Волны гасят ветер...
PM MAIL   Вверх
Baa
Дата 31.12.2002, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2639
Регистрация: 12.4.2002
Где: Москва

Репутация: 8
Всего: 12



Всем спасибо за обсуждение.


--------------------
"Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande
PM ICQ   Вверх
Страницы: (2) [Все] 1 2 
Закрытая темаСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0814 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.