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;
|
тогда и пересоздавать ничего не нужно
|
|
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. Гораздо быстрей работал.
Для интегральных типов — вроде все равно (пишу вроде потому-что, учитывая как они работают, реализация должна быть разная ), хотя есть приколы:
void func(int &value){ value++;}
int i1 = 0;
func(++i);
func(i++);
Четыре инкремента. а результат чему равен?
Но если серьезно, то это азы.
а вообще — это же все виртуально. Есть сомнения пробуй. Хочешь сравнить — напиши пару циклов и сравни скорость. И так во всем.
Только так можно чему-то научиться.
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
|
Круто. У меня так не получилось
|
|
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 Георгий:
В чем разница того что ты написал от того, что я сказал в первом абзаце предыдущего поста?
To Daan:
Чтобы узнать, что ты там проспал — набери пример, что я тебе запостил,
ставь точку останова на первую строку, как запустишь жми Ctrl+Alt+C и дальше по шажкам смотри как оно работает с временными переменными.
QUOTE | Я студент и => только учусь. Поэтому мне свойственно сомневатся, ошибаться и тому подобное. |
Сомневаться следут всем. И проверять свои сомнения.
А фраза — мне свойственно ошибаться — звучит посильней чем "Фауст" Гетте.
"Я глючу, следовательно я существую" decart.exe (с) чейто ориджин на каком-то форуме
|
|
Георгий |
Отправлено: 08.04.2004, 22:12 |
|
Почетный железнодорожник
Группа: Модератор
Сообщений: 874
|
QUOTE | В чем разница того что ты написал от того, что я сказал в первом абзаце предыдущего поста? |
Никакой, но у меня с картинками
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
|
Здравствуйте.
Как-то странно вы память выделяете...
calloc(10,10*sizeof(int)); это десять элементов размером 10*4 байт.
Вы явно этого хотели?
Наверное так правильнее:
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
|
|
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 не пробовал? Это немного ближе к просто выделению памяти
в памяти вектор полностью идентичен указателю на область памяти.
Если есть vector V и требуется получить указатель на данные, то ему даже можно так делать: &V[0]
|
|
Дмитрий |
Отправлено: 09.04.2004, 13:27 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 3
|
я могу быть не прав, ибо начинающий.
надо будет почитать.
Странно, но у Архангельского книга на 1200стр, а нифига про это нет... |
|
Asher |
Отправлено: 09.04.2004, 13:43 |
|
Мастер участка
Группа: Модератор
Сообщений: 550
|
Правильная книга — это
"Язык программирования С++"
специальное издание.
Бьерн Страуструп.
там есть все что вам пока нужно.
|
|
Дмитрий |
Отправлено: 09.04.2004, 14:16 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 3
|
Хорошо, поищу,
спасибо! |
|
Daan |
Отправлено: 10.04.2004, 11:38 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 62
|
Кстати, На ветке задавался вопрос о размере выделения памяти и там "klen" говарил что-то типа предыдущих 2 байт, что это вроде как размер, правда выделенный calloc. |
|