C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Выделение памяти(размышления), next:размер динамического массива sizeof
Daan
  Отправлено: 07.04.2004, 12:15


Дежурный стрелочник

Группа: Участник
Сообщений: 62



Меня как студента изечающего с++, возникли таки размашления:
В C мы выделяем память с помощю malloc, calloc. В C++ принципиально используем new и не что иначе!!!
Вот вопрос а чем лучше то new???
На сколько я понимаю new выделяет память вызывая конструктор, а malloc просто выделяет память!!!!! Но вот например задача: у нас есть массив
{
int *mas = new int[n];
}
и нам в определеный момент нужно увеличить на "к" элементов!! И как это делается??? С маллоком проще есть ремаллок. а с нев надо еще с временной переменной возится!!!!

Кто что думает на эту тему!!!!
xTrim
Отправлено: 07.04.2004, 12:38


Машинист паровоза

Группа: Участник
Сообщений: 208



Немного не туда, но всеже. Раз уж с++ то
CODE

std::vector<int> mas;

тогда и пересоздавать ничего не нужно biggrin.gif
Daan
Отправлено: 07.04.2004, 13:44


Дежурный стрелочник

Группа: Участник
Сообщений: 62



>xTrim
Да ты прав это ты куда-то не туда!!! Это можно защитать решение задачи!!! Но суть размышления не в этом. Но всеже это предложение.
"Выделение памяти" — вот тема. Я хочу узнать, что вы думаете об этом и что вы знаете!!! 1. мне это самому интересно. 2. Будет воозможность узнать об этом больше особенностей, не только мне но и вам.
как например чем лучше пользоваться для увеличения значения аперанда на 1, i++; или ++i; :)
olegenty
Отправлено: 07.04.2004, 15:49


Ветеран

Группа: Модератор
Сообщений: 2412



Ничто не лучше, если не стоит в описании оператора цикла.
(напимер
CODE
for (int i = 0; i < 100; [i++][++i])
{
   ...
}
)
++i  — инкремент до итерации цикла.
i++ — инкремент после итерации цикла.

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

касаемо оператора new ты прав, где тебе не нужен вызов конструктора, пользуйся, чем хочешь. а насчёт realloc... ну и пиши динамически распределяющий память класс... и пользуйся в нём, для выделения памяти под конечные простые элементы, чем хочешь. суть new не быть лучше или хуже malloc, а вызывать конструктор класса.
Asher
Отправлено: 07.04.2004, 17:07


Мастер участка

Группа: Модератор
Сообщений: 550



Привет.
Нормальная реализация new по сути просто обертка для malloc и компании. С возможностью инициализации полученной области памяти (читай — вызов конструктора)

Если пользуешься указателем — то лучше ++i. Гораздо быстрей работал. biggrin.gif
Для интегральных типов — вроде все равно (пишу вроде потому-что, учитывая как они работают, реализация должна быть разная wink.gif ), хотя есть приколы:
void func(int &value){ value++;}
int i1 = 0;
func(++i);
func(i++);
Четыре инкремента. а результат чему равен? biggrin.gif biggrin.gif biggrin.gif
Но если серьезно, то это азы. biggrin.gif

а вообще — это же все виртуально. Есть сомнения пробуй. Хочешь сравнить — напиши пару циклов и сравни скорость. И так во всем.
Только так можно чему-то научиться.

P.S. Парадокс образования: Научить нельзя, но научиться можно.
olegenty
Отправлено: 08.04.2004, 07:48


Ветеран

Группа: Модератор
Сообщений: 2412



это не парадокс, это неверный подход к обучению. суть должна сводиться к подтверждению практикой ХОРОШЕЙ теории.

помню препода в институте, ещё по паскалю. всю теорию знал наизусть. гад. (мне тоже пришлось её читать из-за него). но двух строк кода связать не мог.
Георгий
Отправлено: 08.04.2004, 11:15


Почетный железнодорожник

Группа: Модератор
Сообщений: 874



извините за очевидный ответ, на фоне высоких материй, нашедших в этой ветке убежище.

malloc только захвытывает память.
new захватывает и для каждого элемента вызывает конструктор по умолчанию.
в результате malloc можно использовать талько для захвата памяти под массивы базовых типов, которые конструировать не надо (int, char, указатели и т.п.)
а с помощью new можно создавать массивы объктов, которые требуют своей инициализации. Как пример:
CODE
class Test
       {
       public:
       int local;
       Test(void)
               {
               static int counter;
               local=counter++;
               };
       };
void __fastcall TForm1::Button1Click(TObject *Sender)
{
const nElem=20;
Test *ptrTest=new Test[nElem];
for (int i=0;i<nElem;i++)
       this->Memo1->Lines->Add(ptrTest[i].local);

CODE
Test *ptrTest=new Test[nElem];

создаётся и корректно инициализируется массив объектов
CODE
for (int i=0;i<nElem;i++)
       this->Memo1->Lines->Add(ptrTest[i].local);

демонстрация корректной инициализации всех элементов массива.

надеюсь об принципиальных отличиях new и malloc рассказать удалось.
olegenty
Отправлено: 08.04.2004, 14:37


Ветеран

Группа: Модератор
Сообщений: 2412



Круто. У меня так не получилось biggrin.gif
Daan
Отправлено: 08.04.2004, 14:47


Дежурный стрелочник

Группа: Участник
Сообщений: 62



>olegenty
Да преподы разные бывают. У меня препадователь вообще сепер. На лекции к нему, правда, лучше без подготовки не приходить все равне нифига не поймешь. Но по практике зверь, разорвет любого, мне кажется что он компиляторы в машином коде знает!!!!

>Asher
Вообщето я вспомнил про ++ потому что мы это недавне на лекции проходили. перегрузка оператора

class ...
{
... operator+(...);
};
и вот препод о котором я говарил выше про эту замуты говарил что лучше всего ++i, там какая то лажа с адресацией иль времеными перемаными, не помню, я в то время спал на задней парте:)))


ЗЫ% Я студент и => только учусь. Поэтому мне свойственно сомневатся, ошибаться и тому подобное.

Ну что камуни-буть понравились такие "размышления"??? Они ещё не закончены!
Daan
Отправлено: 08.04.2004, 14:48


Дежурный стрелочник

Группа: Участник
Сообщений: 62



>olegenty
Да преподы разные бывают. У меня препадователь вообще сепер. На лекции к нему, правда, лучше без подготовки не приходить все равне нифига не поймешь. Но по практике зверь, разорвет любого, мне кажется что он компиляторы в машином коде знает!!!!

>Asher
Вообщето я вспомнил про ++ потому что мы это недавне на лекции проходили. перегрузка оператора

class ...
{
... operator+(...);
};
и вот препод о котором я говарил выше про эту замуты говарил что лучше всего ++i, там какая то лажа с адресацией иль времеными перемаными, не помню, я в то время спал на задней парте:)))


ЗЫ% Я студент и => только учусь. Поэтому мне свойственно сомневатся, ошибаться и тому подобное.

Ну что камуни-буть понравились такие "размышления"??? Они ещё не закончены!
Asher
Отправлено: 08.04.2004, 15:13


Мастер участка

Группа: Модератор
Сообщений: 550



Привет всем.

To Георгий:
В чем разница того что ты написал от того, что я сказал в первом абзаце предыдущего поста? biggrin.gif

To Daan:
Чтобы узнать, что ты там проспал — набери пример, что я тебе запостил,
ставь точку останова на первую строку, как запустишь жми Ctrl+Alt+C и дальше по шажкам смотри как оно работает с временными переменными.
QUOTE
Я студент и => только учусь. Поэтому мне свойственно сомневатся, ошибаться и тому подобное.

Сомневаться следут всем. И проверять свои сомнения.
А фраза — мне свойственно ошибаться — звучит посильней чем "Фауст" Гетте. biggrin.gif biggrin.gif biggrin.gif
"Я глючу, следовательно я существую" decart.exe (с) чейто ориджин на каком-то форуме
Георгий
Отправлено: 08.04.2004, 22:12


Почетный железнодорожник

Группа: Модератор
Сообщений: 874



QUOTE
В чем разница того что ты написал от того, что я сказал в первом абзаце предыдущего поста?

Никакой, но у меня с картинками smile.gif

QUOTE
Ну что камуни-буть понравились такие "размышления"???

мне понравились — об отличиях в плане производительности между ++() и ()++ не задумывался.
** Дмитрий
  Отправлено: 09.04.2004, 09:17


Не зарегистрирован







Ага, я по адресу зашел значит.
я тут с дельфей перехожу на С.
вопрос такой: как выглядит на С реализация функции copy?
в дельфи есть такое:
CODE

var a,b:array of integer;
...
setlength(a,10);
b:=copy(a,0,length(a));


а в С такое:
CODE

int *a;
int *b;
a=(int*)calloc(10,10*sizeof(int));
//типа выделили память под 10 элементов
b=....

вот вместо троеточия надо вставить аналогию паскалевского copy
а вот как она выглядит?
Asher
Отправлено: 09.04.2004, 09:46


Мастер участка

Группа: Модератор
Сообщений: 550



Здравствуйте.
Как-то странно вы память выделяете... wink.gif
calloc(10,10*sizeof(int)); это десять элементов размером 10*4 байт.
Вы явно этого хотели? biggrin.gif
Наверное так правильнее:
a=(int*)calloc(10,sizeof(int));
b=(int*)calloc(10,sizeof(int));//Для и память все равно надо выделять
memcpy(b, a, 10*sizeof(int));//Копировать

Переходите на С или С++?
а то можно так:
int *a = new int[10];//массив на 10 байт
int *b = new int[10];//еще один массив на 10 байт
memcpy(b, a, 10*sizeof(int));
а в конце не забывать
delete [ ] b;
delete [ ] a;
Guest
Отправлено: 09.04.2004, 10:08


Не зарегистрирован







а, ну да.
с умножением на 10 это я переборщил.
значит
QUOTE

memcpy(b, a, 10*sizeof(int));//Копировать


Это хорошо. спасибо!
а в дельфи есть
функция, возвращающая длину динамического массива — length();
есть ли в С++ аналог? а то как-то не очень удобно держать дополнительную переменную, в которую постоянно запоминать изменения длины.

да, я перехожу на С++,
я так понял следующий код больше подходит для С++:
CODE

int *a = new int[10];//массив на 10 байт


тогда вопрос — можно ли после такого объявления массива *а изменять его размер с помощью той же функции realloc, или в С++ есть свои для этого средства?
Asher
Отправлено: 09.04.2004, 10:51


Мастер участка

Группа: Модератор
Сообщений: 550



Лучше пользоваться
std::vector biggrin.gif
olegenty
Отправлено: 09.04.2004, 11:33


Ветеран

Группа: Модератор
Сообщений: 2412



а можно DynamicArray
всё от задачи зависит...
Дмитрий
Отправлено: 09.04.2004, 11:36


Ученик-кочегар

Группа: Участник
Сообщений: 3



Насчет victor не согласен — он делает все раз в 10 дольше, проверено.
Если DynamicArray такой же класс, то и он не подойдет.

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

да, на дельфи это проще делается, однако.
olegenty
Отправлено: 09.04.2004, 12:23


Ветеран

Группа: Модератор
Сообщений: 2412



DinamicArrаy суть
array of с незадданым в оприсании размером (если уж об object pascal говорить)
Asher
Отправлено: 09.04.2004, 12:23


Мастер участка

Группа: Модератор
Сообщений: 550



C какого такого перепугу vector в 10 раз медленнее?
потому что ты .resize делал? а .reserve не пробовал? Это немного ближе к просто выделению памяти smile.gif
в памяти вектор полностью идентичен указателю на область памяти.
Если есть vector V и требуется получить указатель на данные, то ему даже можно так делать: &V[0]
Дмитрий
Отправлено: 09.04.2004, 13:27


Ученик-кочегар

Группа: Участник
Сообщений: 3



я могу быть не прав, ибо начинающий.
надо будет почитать.
Странно, но у Архангельского книга на 1200стр, а нифига про это нет...
Asher
Отправлено: 09.04.2004, 13:43


Мастер участка

Группа: Модератор
Сообщений: 550



Правильная книга — это
"Язык программирования С++"
специальное издание.
Бьерн Страуструп.
там есть все что вам пока нужно. biggrin.gif
Дмитрий
Отправлено: 09.04.2004, 14:16


Ученик-кочегар

Группа: Участник
Сообщений: 3



Хорошо, поищу,
спасибо!
Daan
Отправлено: 10.04.2004, 11:38


Дежурный стрелочник

Группа: Участник
Сообщений: 62



Кстати, На ветке задавался вопрос о размере выделения памяти и там "klen" говарил что-то типа предыдущих 2 байт, что это вроде как размер, правда выделенный calloc.

Вернуться в Вопросы программирования в C++Builder