выделение памяти в C ++

Можно ли с помощью оператора «новый» выделить произвольный блок памяти? В C я могу сделать это как "void * p = malloc (7);" - это выделит 7 байтов, если выравнивание памяти установлено на 1 байт. Как сделать то же самое в C ++ с новым оператором?


person user132349    schedule 02.07.2009    source источник


Ответы (8)


Произвольные блоки памяти могут быть выделены с помощью operator new в C ++; не с оператором new, который предназначен для создания объектов.

void* pBlock = ::operator new(7);

Впоследствии такие блоки можно освободить с помощью operator delete.

::operator delete(pBlock);

Обратите внимание, что operator new будет выделять память, выровненную соответствующим образом для любого типа объекта, поэтому реализация может не выделять ровно семь байтов и не более, но то же самое (обычно) верно для malloc. Клиенты C malloc обычно тоже нуждаются в выровненной памяти.

person CB Bailey    schedule 02.07.2009
comment
+1 за упоминание об этом это способ сделать это без malloc и free :) - person Johannes Schaub - litb; 02.07.2009
comment
Кроме того, имейте в виду, что оператор new обычно в любом случае просто перекладывает ответственность на malloc () (в каждой реализации, о которой я знаю). Как сказал Доминик, можно просто использовать malloc. - person Drew Hall; 02.07.2009
comment
Большое спасибо. Это ответ (:: оператор новый). Я потратил много времени, пытаясь понять, почему :: new (x); не работает :) - person user132349; 06.07.2009

Другие ответили на вопрос, как написано, но я хотел бы предложить придерживаться malloc / free для таких распределений.

new и delete предназначены для размещения объектов. Они выделяют необходимую память и вызывают конструкторы / деструкторы. Если вы знаете, что вам просто нужен произвольный блок памяти, использование malloc и free вполне разумно.

person dma    schedule 02.07.2009
comment
Но если вы пишете код на C ++, я думаю, что лучше использовать new / delete, поскольку вы будете использовать его для выделения объектов. Наличие двух типов функций распределения памяти добавляет путаницы. - person Naveen; 02.07.2009
comment
-1. new / delete - это языковые конструкции, которые обеспечивают безопасность типов независимо от того, что вы выделяете / освобождаете. malloc / free - артефакты, оставшиеся для обратной совместимости. - person sharkin; 02.07.2009
comment
@RA, если кому-то нужен произвольный общий блок байтов, нет никакого смысла верить, что они конкретно char или unsigned char или что-то еще - void * более честен и явен. +1 за malloc! - person Alex Martelli; 02.07.2009
comment
OP явно заявляет, что они ожидают возврата пустого указателя. Таким образом, использование new / delete приведет к появлению типов, которые могут им не понадобиться. Если на самом деле прецедент представляет собой массив типов, полностью переключитесь на new []. Если они просто управляют блоком памяти, нет причин вводить типы. - person dma; 02.07.2009
comment
+1 отсюда. Да, безопасность типа new / delete add, но если он не хочет выделять какие-либо конкретные типы, а просто пустой буфер памяти, то malloc / free делает именно это. - person jalf; 02.07.2009
comment
Хотя вы должны пройти через оператор new, как принятый ответ, потому что они могут быть переопределены, чтобы что-то сделать. - person GManNickG; 12.08.2009

Вы не можете выделить void указатель с помощью оператора new C ++: вам придется выделить явный тип, такой как char или uint8_t:

char *p = new char[7];
uint8_t *q = new uint8_t[7];
...
delete [] p;
delete [] q;
person Adam Rosenfield    schedule 02.07.2009

Да, можете.
Но в зависимости от того, что вы делаете, могут быть методы получше.

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

Пример:
Если вы динамически выделяли буфер для чтения из сокета (поскольку размер неизвестен во время компиляции). Альтернативой было бы использование вектора и его динамическое изменение размера. Затем вы можете получить указатель на внутреннюю часть буфера, взяв адрес первого элемента.

person Martin York    schedule 02.07.2009

Лично я бы использовал std::vector<char>. Вы не только получаете произвольный блок байтов (гарантированно смежные), вы получаете их в оболочке RAII. Конечно, нет необходимости использовать какие-либо методы std::vector (кроме, может быть, resize()), но за это нет наказания:

std::vector<char> buffer(7);
void* p = &buffer[0];

Вы можете использовать std::string, но std::string подразумевает, что «этот объект содержит символы, которые имеют смысл при распечатке», где std::vector<char> подразумевает, что «этот объект содержит произвольную группу байтов».

person Max Lybbert    schedule 02.07.2009

Думаю, вы ищете Новое размещение.

person Michael Kristofik    schedule 02.07.2009
comment
Я бы только добавил, что если вы собираетесь использовать такую ​​технику, как Placement New, ВЫ ДОЛЖНЫ БЫТЬ ОСТОРОЖНЫ. Используйте его только в случае крайней необходимости !! - person Mike Dinescu; 02.07.2009
comment
Как размещение new связано с распределением памяти? - person avakar; 02.07.2009
comment
@Miky D: Я согласен, поэтому на связанной странице написано ОПАСНОСТЬ заглавными буквами. :-) - person Michael Kristofik; 02.07.2009
comment
Возможно, я неправильно понял вопрос, но я считаю, что он спрашивает как раз об обратном. То есть не о том, как создать / инициализировать объект в уже выделенном пространстве памяти, а о том, как выделить память без выполнения вызова конструктора. - person David Rodríguez - dribeas; 02.07.2009

новый символ [7];

Традиционно char - это байт, хотя вы можете найти некоторые библиотеки, которые определяют тип BYTE.

person Stefan Mai    schedule 02.07.2009
comment
Не имеет значения; char - это наименьший тип, с которым может справиться реализация. Если char имеет размер 16 бит, то тип байта не может быть меньше 16 бит. Помните, что sizeof (char) == 1. Всегда. - person David Thornley; 02.07.2009
comment
@ Дэвид Торнли: sizeof (char) не обязателен 1, иначе всякие библиотеки маршаллинга будут ужасно расстроены. - person florin; 02.07.2009
comment
@florin: sizeof (char) == 1 по стандарту. См. Раздел 5.3.3 стандарта ISO / IEC 14882: 2003. sizeof (char), sizeof (подписанный char) и sizeof (unsigned char) равны 1; результат применения sizeof к любому другому фундаментальному типу (3.9.1) определяется реализацией. - person Evan Teran; 02.07.2009
comment
Гм, да, sizeof (char) == 1. По крайней мере, в соответствии с разделом 5.3.3 стандарта ISO C ++ (open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2914.pdf), но давайте не будем скучать, я понравился этот ответ на вопрос больше: parashift.com/ c ++ - faq-lite / intrinsic-types.html # faq-26.1 - person Andreas Magnusson; 03.07.2009
comment
@Andreas: разве я не это сказал? - person Evan Teran; 03.07.2009
comment
@Evan: Я написал комментарий одновременно. Ваш комментарий не был виден, пока я не нажал кнопку. Поскольку у меня есть несколько хороших отзывов, я решил оставить его, хотя в основном он говорит то же самое. - person Andreas Magnusson; 06.07.2009

Вы можете сделать char* pBuffer = new char[7];, а поскольку sizeof (char) составляет 1 байт, вы можете использовать его как байтовый буфер. Также не забудьте использовать delete[] (с []) при освобождении памяти.

person Naveen    schedule 02.07.2009