Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: Как увеличить массив не уничтожая его?  (Прочитано 40040 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« : 23-03-2005 14:22 » 

Помнится в одной теме это уже обсуждалось, но я ее найти не могу, а вопрос вроде даже и не вопрос, поэтому думаю ответ получу быстро Улыбаюсь
Так вот есть массив
char *str;
str=new char [12];

Как мне добавить в него еще 3(не важно сколько) элемента? Функция вроде такая есть (если я ничего не путаю) чтобы к массиву, не уничтожая его, добавить новые элементы.
Надеюсь корректно выразился.
Записан

ещё один вопрос ...
Alf
Гость
« Ответ #1 : 23-03-2005 14:40 » 

Это невозможно. Во-первых, подсистема распределения памяти в куче выделила под *str лишь 12 байт. Если массив прибавит себе еще несколько байт "самозахватом", то подсистема ничего об этом не узнает, и при следующем выделении памяти с большой вероятностью разместит в этой области другие объекты, которые испортят добавленный к массиву хвост (или он их испортит первым, смотря по ситуации).

Во-вторых, если после выделения памяти под массив были другие обращения к new, то скорее всего по адресу str+12 уже расположено что-то другое, и расти массиву больше некуда.

Единственное приемлемое решение в данном случае - это создать новый массив требуемого размера, скопировать в него все элементы старого, а область памяти, занятую старым, вернуть обратно через delete[]. Можно либо сделать это вручную, либо воспользоваться контейнерами из стандартной библиотеки, которые обучены подобным фокусам и могут расширяться при необходимости.
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 23-03-2005 14:47 » 

Про вручную понял, спасибо, а что за стандартные контейнеры, хотя бы один для примера.
Записан

ещё один вопрос ...
Alf
Гость
« Ответ #3 : 23-03-2005 14:59 » 

Например, погляди контейнер vector из STL. В нем есть метод resize. Если новый размер больше старого, то к нему добавятся новые элементы в хвост, а если меньше - произойдет усеечение.
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 23-03-2005 16:33 » 

STL, я с ней никогда не связывался и пока думаю не стоит, надо выждать Ага.
Alf, спасибо!!!
Записан

ещё один вопрос ...
Михалыч
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 23-03-2005 16:47 » 

ожидание не поможет Отлично
Да нет там ничего особенно сложного. А жизнь облегчает капитально. Чем раньше начнешь - тем раньше освоишь.
Единственное неудобство (ну может это мое субъективное) отладка проблематичнее. Мягко говоря не очень удобно залезть отладчиком и посмотреть содержимое элемента того же вектора.
Записан

Поживем - увидим... Доживем - узнаем... Выживу - учту  Улыбаюсь
Pu
Большой босс

ru
Offline Offline
78


« Ответ #6 : 24-03-2005 07:13 » new

Михалыч, я для отладки пользуюсь вот таким методом, может и криво но посмотреть мона любые типы.   
Код:
       std::vector<int> v;
for( int i = 0; i<100; i++)
v.push_back( i);
int *g = new int[v.size()];
std::copy( v.begin(), v.end(), g); //после копирования можно посмотреть в массиве любые значения по индексу, чего не получается в векторе
delete []g;
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
Pu
Большой босс

ru
Offline Offline
78


« Ответ #7 : 24-03-2005 07:21 » 

nikedeforest, чем обусловлено нежелание уничтожать массив. Если ты хранишь гдето указатель на массив и потом после увеличения его пытаешься использовать, то в этом случае тебе можуть помочь только связанные списки в STL это std::list. Там после перераспределения памяти элементы остаются на своих местах. А при использовании std::vector элементы перемещаются в памяти чтобы занимать непрерывную область. Так жеж в этом случае не поможуть и функции malloc - realloc.
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #8 : 24-03-2005 08:16 » 

Жуть ИМХО... Чего вы насоветовали...

Слухай сюды:

1. Записи
char str[12];
и
char * str=(char *)malloc(12);
равнозначны по занятой памяти и методу обращения к ним.

И там и там можно писать
str[5]='a';

2. Во втором случае можно:
str=(char *)realoc((void *)str,newsize);
где newsize = 12+n; // n - новая необходимая к добавлению длина...

При использовании не char = 1 bite, а int писать надо:
Код:
int *test_param;
int size=100;
int increment=1000;
test_param = (int *malloc(size*sizeof(int));

....
....
test_param = (int *)realloc((void *)test_param,(size+increment)*sizeof(int));
Всегда надо помнить что в С и С++ массив и типизированный указатель можно использовать одинаково, с единственной разницей - указатель надо высвобождать free(test_param);
« Последнее редактирование: 20-12-2007 20:09 от Алексей1153++ » Записан

А птичку нашу прошу не обижать!!!
Pu
Большой босс

ru
Offline Offline
78


« Ответ #9 : 24-03-2005 10:11 » 

Гром, я вот о чем, в приведеном коде сохраняется указатель на выделенную память в указатель с1. после операции реаллок он будет уже показывать на невалидные данные. попытка воспользоваться им приведет к .... сам знаешь Ага.

Код:
char *c1;

int main()
{
char *c = (char *)malloc(12);
       с1 = с;
char *t = (char *)malloc(12);
c = (char *)realloc( c, 20); // теперь указатель с1 будет показывать на черт знает что
free(c);
free(t);
return 0;
}
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #10 : 24-03-2005 10:14 » 

Гром, я вот о чем, в приведеном коде сохраняется указатель на выделенную память в указатель с1. после операции реаллок он будет уже показывать на невалидные данные. попытка воспользоваться им приведет к .... сам знаешь Ага.

Код:
char *c1;

int main()
{
char *c = (char *)malloc(12);
 с1 = с;
char *t = (char *)malloc(12);
c = (char *)realloc( c, 20); // теперь указатель с1 будет показывать на черт знает что
free(c);
free(t);
return 0;
}

А что мешает дописать:
с1 = с;
после realloc???
Как и всегда - отслеживание состояние указателя лежит на программисте.
Записан

А птичку нашу прошу не обижать!!!
Alf
Гость
« Ответ #11 : 24-03-2005 10:22 » 

Как и всегда - отслеживание состояние указателя лежит на программисте.

Некрасиво все-таки. Компилятором C++ пользуем программу, написанную практически на чистом С. Для того и ввели объектные заморочки, чтобы писать надежные программы без побочных сюрпризов. А тут придется чесать репу, обнаружив, что Вася в своей подпрограмме изволил передвинуть массив, которому стало тесно, и не предупредил Петю, который в начале программы сохранил на него ссылку и теперь диву дается, куда подевались его данные. Можно, конечно, выпороть Васю на конюшне за саботаж, а можно воспользоваться надежными объектами, которые таких фокусов не допустят и не потянут особых накладных расходов.
Записан
Pu
Большой босс

ru
Offline Offline
78


« Ответ #12 : 24-03-2005 10:32 » 

Alf, абсолютно согласен. И уже давненько отказался от такого рода практики, можно привести массу примеров когда нарывался на трудноуловимые ошибки. Щас контейнеры и только контейнеры. Слава богу реализация их у меня  вызывает все больше восхищения. Да есть их на все случаи жизни. Плюс алгоритмы. Короче репу морщить не надо. Улыбаюсь
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #13 : 24-03-2005 10:33 » 

Альф  Улыбаюсь
Не смеши Улыбаюсь

Я вообще не помню в своей практике realloc-a Если надо - делается динамический список данных или LinkedList или дерево.
Записан

А птичку нашу прошу не обижать!!!
Alf
Гость
« Ответ #14 : 24-03-2005 10:50 » 

Альф Улыбаюсь
Не смеши Улыбаюсь

Я вообще не помню в своей практике realloc-a Если надо - делается динамический список данных или LinkedList или дерево.

Ну вот сам и признался, каков ты хитрец  Ага

Сам пишешь корректно, а других всяким низкоуровневым гадостям учишь вроде realloc.
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #15 : 24-03-2005 11:46 » 

Стоп - не правда ваша Улыбаюсь
Был конкретный вопрос про массив - я конкретно ответил про массив.

Бывает такое, например рекурсия, когда заполнение данных в массив выгоднее чем в списки - и тогда лучше использовать realloc я признаю забыл что делал такое....

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

А птичку нашу прошу не обижать!!!
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 24-03-2005 16:23 » 

Ну и дискуссия Улыбаюсь.
Гром, кажется твой совет я и имел ввиду когда пытался его вспомнить. В какой-то теме ты его предлагал Алексею1153 (если я ничего не путаю), кстати тогда он не вызвал столько отрицательных эмоций, но теперь была возможность оценить плюсы и минусы, спасибо за очередной глоток знаний.
По прочтению постов возник вопрос: Что такое LinkedList? Кажется я с этим еще не сталкивался Жаль.
Записан

ещё один вопрос ...
Михалыч
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 24-03-2005 16:24 » 

to Pu
Цитата
Михалыч, я для отладки пользуюсь вот таким методом, может и криво но посмотреть мона любые типы.   
Дык, кто бы спорил... Отлично
Я же и говорю - несколько неудобно и с извращениями типа промежуточных массивов, но можно.
Все это правда окупается несомненным удобством применения STL.

to Alf
Цитата
Сам пишешь корректно, а других всяким низкоуровневым гадостям учишь вроде realloc.
Если касательно только этого момента с массивом - то да... И то не гадость. Не одним С++ -ом живем. Просто С еще никто со счетов не сбрасывал. Есть применимость и не маленькая. Другое дело что не везде. Во встраиваемых приложениях, например. Правда тоже не везде. Это не ради дискуссии, поскольку она по этому поводу (на мой взгляд) бессмысленна, просто у тех кто только начинает может сложиться неадекватное впечатление о языке Улыбаюсь
Записан

Поживем - увидим... Доживем - узнаем... Выживу - учту  Улыбаюсь
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #18 : 24-03-2005 16:28 » 

Liinked List - связный список
Записан

А птичку нашу прошу не обижать!!!
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 24-03-2005 16:56 » 

А это что инструмент, алгоритм, функция Не понял
Записан

ещё один вопрос ...
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #20 : 24-03-2005 18:15 » 

Тип данных - который состоит из полей связанных между собой указателями...

Нифига себе какой пробел в знаниях Улыбаюсь
Записан

А птичку нашу прошу не обижать!!!
Pu
Большой босс

ru
Offline Offline
78


« Ответ #21 : 24-03-2005 18:20 » 

nikedeforest, из названия следует - связанный список , те в стл это контейнер std::list. суть в том что элементы располагаются в памяти не подряд, а с разрывами, как попало. Каждый элемент имеет ссылки на предыдущий и последующий член. Доступ по индексу в таких контейнерах затруднен, тк приходится от текущего перебрать все элементы до нужного. зато алгоритмы сортировки и типа того работают эффективнее не надо физически перемещать элементы, просто пересвязать указатели и все.
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
Alf
Гость
« Ответ #22 : 24-03-2005 20:23 » 

...
to Alf
...у тех кто только начинает может сложиться неадекватное впечатление о языке Улыбаюсь

Согласен на 100%. Почти полная обратная совместимость С++ и С провоцирует использовать рудименты вроде malloc, всяких макроопределений и тому подобных устаревших конструкций там, где вполне можно обойтись более выразительными и безопасными новыми средствами языка. При этом программист совершенно искренне заблуждается, считая, что пишет на С++, ведь компилятор не выдает ни единой ошибки, да и программа вроде работает корректно (пока не пришлось ее модифицировать или передать на сопровождение коллеге, который не успел разгадать все ребусы с периодически кочующими массивами и т.п.).

IMHO эта обратная совместимость с предшественником оказывает сегодня языку такую же медвежью услугу, как и обратная совместимость последних процессоров Intel с динозавром 8086, в результате которой мы имеем технологически совершенный кристалл, работающий на невообразимых частотах и при этом имеющий искалеченную архитектуру с ограниченным набором регистров общего назначения, которые фактически таковыми не являются, архаичным аккумулятором, извращенными методами адресации, непонятной пристройкой в виде сопроцессора с плавающей точкой... Словом, обычный популистский шаг, который сначала дает некоторое преимущество, позволяя сохранить приверженцев прежней модели, не готовых к радикальным переменам концепции, а потом оказывается тяжкой гирей на ногах, которая мешает двигаться дальше.
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 24-03-2005 21:32 » 

Цитата
Нифига себе какой пробел в знаниях  Улыбаюсь
Гром, в реалии этот пробел еще больше Жаль.
Pu, спасибо, доступно объяснил.

Цитата
Словом, обычный популистский шаг, который сначала дает некоторое преимущество, позволяя сохранить приверженцев прежней модели, не готовых к радикальным переменам концепции, а потом оказывается тяжкой гирей на ногах, которая мешает двигаться дальше.
У нас в науку вкладывает гос-во, из-за чего наука нищенствует, а на западе наука сама зарабатывает (или зарабатывают с помощью науки) из-за чего там приходится корректировать прогресс на благо заработка и не совсем в угоду прогрессу. Везде есть свои недостатки.
Записан

ещё один вопрос ...
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #24 : 24-03-2005 21:37 » 

Alf, привет. Тоже не спится? Я вот выбрался из дому, а тут такая дискуссия, но только ты в онлайне. Ну ладно.
Чего они тут воду мутят? Гром, говоря твоими словами - Был конкретный вопрос про массив - Alf конкретно ответил про массив. Нельзя такого сделать. Тем более, что  nikedeforest о чём то таком догадывался - ведь не зря в вопросте стоит "не уничтожая его". Прелесть массивов и заключается в непрерывности блоков данных, чем обеспечивается мгновенный доступ к необходимому блоку простым вычислением его адреса. Но как правильно Alf написал во втором пункте - а ежели дальше нет места? то тогда никуда не денешься придётся искать другой блок подходящих размеров. В независимости програмируется в С или С++.
Кстати, Михалыч, в 2003 студии дебаггер показыват содержимое STL контейнеров. Конечно если это твои типы данных. Так что всё в порядке - проблемм нет.
nikedeforest, - не отчаивайся и не бойся - я начал с знакомство с STL случайно. Как всегда в поисках скудной инфы на русском языке (дело было в конце прошлого тысячелетия) я наткнулся на пример главы из книги
Леена Аммерааля "STL для программистов на C++" - файл в формате pdf - около -30 страниц. Читалось очень легко и главное понятно. Могу только порекомендовать. Теперь вопрос как люди могут програмировать без STL вызывает у меня такое же недоумение как и вопрос, как люди 100 лет назад обходились без пластмассы. Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #25 : 24-03-2005 21:38 » 

nikedeforest, у тебя оказывается тоже бессонница.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #26 : 24-03-2005 21:58 » 

Джон, я полуночник (сова). За рекомендацию спасибо, обязательно ознакомлюсь в ближайшее время. По-видимому настало время браться за STL Улыбаюсь.
Записан

ещё один вопрос ...
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #27 : 24-03-2005 22:05 » 

Непременно надо браться. Если не найдёшь (хотя я думаю с этим проблем не будет) чиркни на мыло. Я тебе файл на мыло кину.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #28 : 24-03-2005 22:07 » 

Джон, буду иметь ввиду Ага
Записан

ещё один вопрос ...
Alf
Гость
« Ответ #29 : 24-03-2005 22:10 » 

Alf, привет. Тоже не спится? Я вот выбрался из дому, а тут такая дискуссия, но только ты в онлайне.

Привет. Тут такой интересный разговор завязался из безобидного поначалу вопроса, что никак проспать нельзя  Улыбаюсь

Столкновение двух точек зрения: "так не следует делать, потому что..." против "но я ведь делал, и у меня все работало!!!"  Улыбаюсь

Это интереснее, чем куски MSDN друг другу цитировать...
Записан
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines