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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с памятью в C/C++ 
:(
    Опции темы
mes
Дата 6.12.2009, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(djamshud @  6.12.2009,  01:56 Найти цитируемый пост)
В него включены абстракции new и delete. Но нету ни возможности изменить размер блока, ни скопировать, ни переместить его

new и delete предназначены для другого..  для работы с памятью смотрите уже упомяннутые Вами стл-аллокаторы.

Цитата(djamshud @  6.12.2009,  01:56 Найти цитируемый пост)
Но вот приделали к new зачем-то функцию создания массивов..

для того что массив не плоских объектов создавать логично именно таким способом. smile

Цитата(djamshud @  6.12.2009,  01:56 Найти цитируемый пост)
. И тут же еще один костыль - черезжопный (синтаксисом) delete[]

Ну это смотря откуда смотреть. 


Цитата(djamshud @  6.12.2009,  01:56 Найти цитируемый пост)
Прям как объект. 

В процессе удаления происходит поочередное удаление всех объектов входящих в состав массива.
delete - удалить один, delete [] удалить много - все логично.

Цитата(djamshud @  6.12.2009,  01:56 Найти цитируемый пост)
. Количество вопросов (не здесь, на винграде, а вообще. А может и здесь много) "как изменить размер массива в с++" как бы намекает на это.

из за незнания средств и политики c++.


Цитата(djamshud @  6.12.2009,  01:56 Найти цитируемый пост)
что дает большую свободу,
Цитата

За что я его и люблю.

И за это же  ненавидят многие другие.. smile

Цитата(djamshud @  6.12.2009,  01:56 Найти цитируемый пост)
Звучит очень красиво. Беглый осмотр не дал подтверждения вашим словам. Можете ткнуть носом, где именно это происходит?

чуть позже - сейчас времени нет..
smile


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


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

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



>для того что массив не плоских объектов создавать логично именно таким способом.

Ну так создать и удалить - это маловато;).

>delete - удалить один, delete [] удалить много - все логично.

Логично delete на все. И пусть сам разбирается, объект там или массив объектов. Ну зачем приделали эти две чертовые скобочки?:). Мне, когда я освобождаю память, в общем-то уже наплевать, что там, и как оно удалится. Вся механика внутри.

>из за незнания средств и политики c++

И из-за отсутствия в нем казалось бы очевидной фичи.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
mes
Дата 6.12.2009, 21:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(bsa @  6.12.2009,  14:58 Найти цитируемый пост)
предлагаю перенести ваш спор в более подходящие для этого место, так как новичкам от него проку никакого.

я не против smile.

Цитата
Звучит очень красиво. Беглый осмотр не дал подтверждения вашим словам. Можете ткнуть носом, где именно это происходит?

у gcc например в файле <bits/stl_uninitialized.h> представлен типоориентированный выбор способа копирования массива (memmove или цикл)

Цитата(djamshud @  6.12.2009,  14:39 Найти цитируемый пост)
Логично delete на все. И пусть сам разбирается, объект там или массив объектов. Ну зачем приделали эти две чертовые скобочки?smile. 

причины две :
1. необходимость универсального доступа посредством указателя, в связи с чем отсуствуют статическая информация о типе
(в противном случае можно было сделать разницу между  int *p и int[] p и общий delete)
2. позиционирование c++ как языка без ненужных оверхедов, в связи с чем необходимая информация, которая могла бы присутствовать в рантайм, также отсуствует. 
(хоть некоторые реализации и идут на встречу пользователю, но это не в счет).


Это сообщение отредактировал(а) mes - 6.12.2009, 21:22


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


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

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



bsa, да мы наверное почти закончили:).

>у gcc например в файле <bits/stl_uninitialized.h> представлен типоориентированный выбор способа копирования массива (memmove или цикл)

А сначала звучало все более многообещающе и фундаментально. Впрочем и то неплохо. Надеюсь, существует возможность и ручной настройки, потому как многие простые классы поддаются memcpy/memmove.

>причины две :

Я так и думал, что это единственные причины. Но что malloc, что new кроме того, что выделяют память и отдают указатель на нее, еще и создают структуры, ассоциированные с этим указателем, в которых описано как минимум, сколько памяти выделено, чтобы потом не оттяпать лишнего. New, видимо, еще хранит какую-то ассоциацию с типом или деструктором типа. Очевидно, что new[] в довесок еще пишет, сколько элементов он создал, а delete[] эту информацию читает. Так почему было не научить обычный delete пользоваться этой информацией? В таком случае при каждом обычном new в эту структуру добавлялся еще один член - длина массива, равная единице. А вот допустим ли оверхед в несколько байт на каждый new, я не знаю. Казалось бы на одни выравнивания вылетает гораздо больше, но они то отключабельны.

Добавлено через 1 минуту и 17 секунд
bsa, ох, я успел сюда ответить. Перенесите это сообщение пожалуйста.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
Lazin
Дата 7.12.2009, 21:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



Цитата(djamshud @  5.12.2009,  22:03 Найти цитируемый пост)
Чувак, я тебе про одно, а ты про другое. Говорить очевидные вещи, когда сказать больше нечего, необязательно. С++ не предоставляет методов для _эффективной_работаты_с_памятью_

что значит _эффективная_работа_с_памятью_? почему в С++ она не эффективная?

Цитата(djamshud @  6.12.2009,  15:39 Найти цитируемый пост)
Логично delete на все. И пусть сам разбирается, объект там или массив объектов. Ну зачем приделали эти две чертовые скобочки?smile. Мне, когда я освобождаю память, в общем-то уже наплевать, что там, и как оно удалится. Вся механика внутри.

ну вообще delete в состоянии удалить и массив, но это противоречит стандарту языка
PM MAIL Skype GTalk   Вверх
djamshud
Дата 8.12.2009, 12:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

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



>что значит _эффективная_работа_с_памятью_? почему в С++ она не эффективная?

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

>ну вообще delete в состоянии удалить и массив, но это противоречит стандарту языка 

Может быть, но по стандарту нужно delete[], а мне кажется, что это лишнее. А если поведение отличается от стандарта, значит остается уповать на реализацию delete в конкретной системе и в случае непредвиденного поведения пинать лишь себя. Valgrind например детектит ошибку в себе:

Код

int main(){
delete new char[1024];
return 0;}


Код

==22622== Mismatched free() / delete / delete []
==22622==    at 0x40236CA: operator delete(void*) (vg_replace_malloc.c:342)
==22622==    by 0x804849E: main (delete.cpp:2)
==22622==  Address 0x42c2028 is 0 bytes inside a block of size 1,024 alloc'd
==22622==    at 0x402403E: operator new[](unsigned int) (vg_replace_malloc.c:268)
==22622==    by 0x8048490: main (delete.cpp:2)


Хотя память таки освобождается
Код
==22622== All heap blocks were freed -- no leaks are possible.



--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
Lazin
Дата 8.12.2009, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



Цитата(djamshud @  8.12.2009,  12:29 Найти цитируемый пост)
е предоставляет _методов_. Плюсовые методы неэффективны, потому как например копирование/перемещение/изменение размера блока делается через одно место. Это было хорошо видно из комментариев в начале топика, откуда нас выгнали.

а через какое место, оно должно делаться?
нужно понимать, что просто взять и скопировав память не POD объекта в принципе нельзя, так-как там могут быть указатели/ссылки на другие объекты, если нужно свободно перемещать/копировать/изменять размер/освобождать участки памяти, то можно ограничиться POD объектами, или в некоторых случаях можно использовать аллокатор для не POD объектов

допустим, есть у нас какой либо алгоритм, который требует для своей работы создания какого-либо набора объектов(не плоских, а содержащих внутри себя ссылки на другие объекты), можно выделить один большой кусок памяти, за один вызов, затем все объекты создать в нем используя алокатор, а затем, когда результат работы алгоритма получен, просто освободить весь участок памяти, (сейчас в меня полетят тухлые яйца) даже не вызывая деструкторы smile  правда, для этого, деструкторы не должны иметь сайд эффектов, а все объекты должны использовать аллокаторы, для выделения/освобождения памяти, а так-же для конструирования и удаления объектов

еще, следует помнить, что С++, это не Си, программа на Си, по сути описывает работу с памятью, программа на С++, описывает типы, описывающие объекты, размещаемые в памяти и их семантику, то-есть, работа с памятью как в Си, по сути - хак, позволяющий обойти любые правила smile 
PM MAIL Skype GTalk   Вверх
MAKCim
Дата 8.12.2009, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


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

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



Цитата(Lazin @  8.12.2009,  12:47 Найти цитируемый пост)
а один вызов, затем все объекты создать в нем используя алокатор, а затем, когда результат работы алгоритма получен, просто освободить весь участок памяти, (сейчас в меня полетят тухлые яйца) даже не вызывая деструкторы

Код

size_t size = sizeof(A) + sizeof(B) + sizeof(C) + sizeof(D);
void *ptr = new char [size];
void *old_ptr = ptr;
A *a = new (ptr) A();
ptr += sizeof(A);
B *b = new (ptr) B();
ptr += sizeof(B);
C *c = new (ptr) C();
ptr += sizeof(C);
D *d = new (ptr) D();
...
error_d:
d->~A();
error_c:
c->~B();
error_b:
b->~C();
error_a:
a->~D();
error:
delete []old_ptr;

а собственно, почему бы и нет  smile 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
djamshud
Дата 8.12.2009, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

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



Lazin, вы конечно все правильно говорите, но не договариваете. И ни единого тухлого яйца не получите. Даже надгрызанного:).

Смотрите, создаем массив. Вдруг нам не хватает памяти (да, это очень низко; скажем на языке более высокого уровня - не хватает места в массиве), хотим его расширить. Через какое место? Через то самое: создаем новый массив, копируем (естественно поэлементно, ибо кусками копировать - это низко и по-сишному), удаляем старый. Захотели скопировать массив? Проделали все операции кроме последней. Почему нельзя было ввести более широкий арсенал действий, который кроме всего прочего еще и применяли бы оптимизированные техники при работе с простыми типами и "плоскими" объектами. Вот это была бы красота.

Вы можете возразить, что это все есть в стл векторе. Но раз уж есть кошерный вектор, нахрена вообще было new[] и delete[] создавать? Наверное на момент их создания вектора еще не было, но тогда опять исходный вопрос:).

MAKCim, суть кода - показать, что можно напрямую вызвать деструктор? Да, здорово;). Имхо из сообщения Lazin'а не следует обратного.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
Lazin
Дата 8.12.2009, 21:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



Цитата(djamshud @  8.12.2009,  20:47 Найти цитируемый пост)
Почему нельзя было ввести более широкий арсенал действий, который кроме всего прочего еще и применяли бы оптимизированные техники при работе с простыми типами и "плоскими" объектами. Вот это была бы красота.

а кто мешает работать с массивом POD типа как одним большим куском памяти?

Цитата(djamshud @  8.12.2009,  20:47 Найти цитируемый пост)
Но раз уж есть кошерный вектор, нахрена вообще было new[] и delete[] создавать? Наверное на момент их создания вектора еще не было, но тогда опять исходный вопросsmile.

сначала хотел что-нибудь возразить, из принципа smile, но потом подумал, что и сам редко пользуюсь этими операторами, как правило тогда, когда нужно использовать массив фиксированного размера
PM MAIL Skype GTalk   Вверх
djamshud
Дата 8.12.2009, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

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



>а кто мешает работать с массивом POD типа как одним большим куском памяти?

Скопировать/переместить можно. Но опять malloc + memчто-то. Ну так это геморно и по-сишному. Хочу, грубо говоря, так: 
Код

char *_old=new[512];
char *_new=copy[](_old);


Вот это по-плюсовому было бы. И опять же нафиг изначально использовать new[], если потом все равно придется пускаться в низкоуровневый пляс?

А расширить блок нормально вообще никак. Realloc по идее плюнется на указатель, созданный new[]. А хочется что-то вроде
Код

_old=resize[2048](_old);


Вот такие они, мои эротические фантазииsmile.

Пока писал, проверил. Не плюнулся. Может быть просто из-за минималистичности примера, а может и более или менее нормально сработало. Хотя valgrind опять хорошенько проматерился. Тут опять видимо тонкости реализации, на которые нельзя полагаться: new и malloc, с которым работает realloc, создают "разные" указатели.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
MAKCim
Дата 8.12.2009, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


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

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



Цитата(djamshud @  8.12.2009,  20:47 Найти цитируемый пост)
суть кода - показать, что можно напрямую вызвать деструктор?

нет, мне просто в тот момент нечего было делать ;) код бессмысленен


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила ведения Религиозных войн
Smartov
1. Уважайте собеседника
2. Собеседник != враг
3. Старайтесь воздерживаться от тем вида "Windows Rulez" или "Linux Rulez"

С уважением, Smartov.

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


 




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


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

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