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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Расширение динамического массива, Из "Указатели, строки, классы и пр." 
:(
    Опции темы
Neytral
Дата 6.9.2007, 21:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Интересует задача создания функции расширяющей динамический массив (функция должна вызываться последовательно несколько раз, т.е. к примеру расширить массив от 0 до 99999 шагом 1), передаваемый ей через список параметров. Собственно это первый пример, который к сожалению выдаёт ошибку.
Код

#include <iostream>
using namespace std;

void func (int *a, int &num)//функция за один вызов увеличивает размер массива на 1
{
    delete [] a;
    num=num+1;//если эту строку убрать - то программа работает!!!! Правда смысл функции при этом теряется :(
    a=new int [num];
}

void main()
{
    int num=0;//содержит текущий размер массива
    int *a=new int [num];//переменная обязательно создаётся вне тела функции
    
    for (int i=0;i<99999;i++)//если количество итераций
                            //цикла ограничить до 3 - работает!!!
        func(a,num);    
    delete[] a;
}

Тот же пример, только без функции - всё работает замечательно!
Код

#include <iostream>
using namespace std;

void main()
{
    int num=0;
    int *a=new int [num];
    
    for (int i=0;i<2007;i++)
    {
        func(a,num);    
        delete [] a;
        num=num+1;
        a=new int [num];    
    }
    delete[] a;
}

У меня Visual C++ 6.0, ставил сервиспаки 1, 2, 4, 5 (ставил все по порядку).

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


Эксперт
****


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

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



Код
#include <iostream>
using namespace std;

void func (int *&a, int &num)//обрати внимание на ссылку
{
    delete [] a;
    num=num+1;
    a=new int [num];
}

void main()
{
    int num=0;//содержит текущий размер массива
    int *a=new int [num];//переменная обязательно создаётся вне тела функции
    
    for (int i=0;i<99999;i++)//если количество итераций
                            //цикла ограничить до 3 - работает!!!
        func(a,num);    
    delete[] a;

}

А лучше это делать через realloc. Хоть и сишная функция, зато меньше гимору.
PM   Вверх
JackYF
Дата 6.9.2007, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

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



Цитата(bsa @  6.9.2007,  21:15 Найти цитируемый пост)
А лучше это делать через realloc.

имхо, лучше это делать через std::vector - это его штатное поведение, - (причем он будет вести себя в этом случае оптимальнее, чем реаллок и такая самописная функция) и не изобретать велосипед.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
bsa
Дата 7.9.2007, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(JackYF @ 6.9.2007,  21:53)
Цитата(bsa @  6.9.2007,  21:15 Найти цитируемый пост)
А лучше это делать через realloc.

имхо, лучше это делать через std::vector - это его штатное поведение, - (причем он будет вести себя в этом случае оптимальнее, чем реаллок и такая самописная функция) и не изобретать велосипед.

логично, и как я сам про него забыл...  smile 
PM   Вверх
Neytral
Дата 7.9.2007, 23:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо, по ссылке заработало, пошел изучать realloc.
PM MAIL   Вверх
bsa
Дата 7.9.2007, 23:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Neytral @ 7.9.2007,  23:44)
Спасибо, по ссылке заработало, пошел изучать realloc.

ты еще и про std::vector почитай. Может он тебе лучше подойдет.
PM   Вверх
UnrealMan
Дата 8.9.2007, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(JackYF @  6.9.2007,  22:53 Найти цитируемый пост)
причем он будет вести себя в этом случае оптимальнее, чем реаллок 

Оптимальнее по скорости в случае POD-типов - это вряд ли.
PM MAIL   Вверх
JackYF
Дата 8.9.2007, 21:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

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



Цитата(UnrealMan @  8.9.2007,  16:51 Найти цитируемый пост)
Оптимальнее по скорости в случае POD-типов - это вряд ли. 

я про другое.

Если я последовательно увеличиваю размер массива от 1 до N, то реаллок сделает N перевыделений памяти, а вектор - около log2(N). Так что не согласен.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
UnrealMan
Дата 9.9.2007, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(JackYF @  8.9.2007,  22:35 Найти цитируемый пост)
Если я последовательно увеличиваю размер массива от 1 до N, то реаллок сделает N перевыделений памяти

Ну так зачем же каждый раз-то realloc вызывать? Кстати, перевыделений, скорее всего, будет меньше - как раз тем realloc и хорош, в отличие от operator new + operator delete.
PM MAIL   Вверх
JackYF
Дата 9.9.2007, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

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



Цитата(UnrealMan @  9.9.2007,  22:08 Найти цитируемый пост)
Ну так зачем же каждый раз-то realloc вызывать?

а что делается в примере кода выше?

Цитата(UnrealMan @  9.9.2007,  22:08 Найти цитируемый пост)
Кстати, перевыделений, скорее всего, будет меньше - как раз тем realloc и хорош, в отличие от operator new + operator delete. 

А std::vector - наверняка еще меньше, причем прозрачно для тебя.



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
UnrealMan
Дата 9.9.2007, 23:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(JackYF @  10.9.2007,  00:22 Найти цитируемый пост)
а что делается в примере кода выше?

Да какая разница? Может, ты скажешь, что такое расширение вектора v

Код
std::vector<Type> tmp(v.size()+1);
std::copy(v.begin(), v.end(), tmp.begin());
v.swap(tmp);

будет быстро работать?

Цитата(JackYF @  10.9.2007,  00:22 Найти цитируемый пост)
А std::vector - наверняка еще меньше, причем прозрачно для тебя.

Меньше за счёт чего?

Это сообщение отредактировал(а) UnrealMan - 9.9.2007, 23:49
PM MAIL   Вверх
Любитель
Дата 9.9.2007, 23:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

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



Уже много раз спорили на эту тему. Вердикт однозначен - в плюсах в 99% случаев использование сишного управления памятью есть зло. Идеологическое зло smile


--------------------
PM MAIL ICQ Skype   Вверх
UnrealMan
Дата 10.9.2007, 00:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Любитель @  10.9.2007,  00:56 Найти цитируемый пост)
Вердикт однозначен - в плюсах в 99% случаев использование сишного управления памятью есть зло. Идеологическое зло

Так-то оно так, но по эффективности realloc (там, где его можно применять именно как средство перераспределения памяти) всё-таки лучше smile
PM MAIL   Вверх
Любитель
Дата 10.9.2007, 00:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

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



Вряд ли лучше. Но даже если так, то эти накладные расходы относительно размера вектора можно считать постоянными и достаточно малыми. Ими стоит пренебречь в 99% случаев smile Поверь, все реализации СТЛ очень нехило оптимизированны.


--------------------
PM MAIL ICQ Skype   Вверх
JackYF
Дата 10.9.2007, 00:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

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



Цитата(UnrealMan @  9.9.2007,  23:43 Найти цитируемый пост)
Да какая разница? Может, ты скажешь, что такое расширение вектора v

Выделить всёкод C++
1:
2:
3:
    
std::vector<Type> tmp(v.size()+1);
std::copy(v.begin(), v.end(), tmp.begin());
v.swap(tmp);

будет быстро работать?

Ужас какой... tmp.reserve(v.size()+1);
tmp.push_back(что_надо);

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




--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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