Можно ли выделить произвольный блок памяти с помощью «нового» оператора? В C я могу сделать это как «void * p = malloc (7);» - это будет выделять 7 байт, если для выравнивания памяти установлено 1 байт. Как сделать то же самое в C++ с новым оператором?выделение памяти в C++
ответ
Произвольные блоки памяти могут быть выделены operator new
в C++; а не с оператором new
, который предназначен для построения объектов.
void* pBlock = ::operator new(7);
Такие блоки могут впоследствии быть освобождены с operator delete
.
::operator delete(pBlock);
Обратите внимание, что operator new
будет выделена память надлежащим образом выровненную для любого вида объекта, поэтому реализация не может выделить ровно семь байт и не более, но то же самое (обычно) относится и к malloc
. Клиенты C malloc
обычно нуждаются в выровненной памяти.
Вы не можете выделить void
указатель с оператором С ++ new
: вам придется выделить явного типа, такие как char
или uint8_t
:
char *p = new char[7];
uint8_t *q = new uint8_t[7];
...
delete [] p;
delete [] q;
Я думаю, что вы могли бы искать Placement New.
Я бы добавил, что если вы собираетесь использовать такие методы, как Placement New, вы должны быть осторожны. Используйте его только в случае необходимости! –
Как новое размещение относится к распределению памяти? – avakar
@Miky D: Я согласен, поэтому связанная страница посыпана словом «ОПАСНОСТЬ» во всех шапках. :-) –
новый знак [7];
Традиционно char является байтом, хотя вы можете найти некоторые библиотеки, которые набирают тип BYTE.
Не имеет значения; char - это наименьший тип, с которым может справиться реализация. Если char имеет 16 бит, тогда байтовый тип не может быть меньше 16 бит. Помните, что sizeof (char) == 1. Всегда. –
@David Thornley: sizeof (char) не требуется 1, в противном случае всевозможные сортировочные библиотеки будут ужасно расстроены. – florin
@florin: sizeof (char) == 1 согласно стандарту. См. Раздел 5.3.3 ИСО/МЭК 14882: 2003. «sizeof (char), sizeof (signed char) и sizeof (unsigned char) равны 1, результат sizeof, применяемый к любому другому фундаментальному типу (3.9.1), определяется реализацией». –
Вы можете сделать char* pBuffer = new char[7];
, а так как sizeof (char) - 1 байт, вы можете использовать его в качестве байтового буфера. Кроме того, не забудьте использовать delete[]
(с []) при освобождении памяти.
Другие ответили на вопрос как написано, но я хотел бы предложить придерживаться malloc/free для таких распределений.
новые и удаленные предназначены для выделения объектов. Они выделяют требуемую память и вызывают конструкторы/деструкторы. Если вы знаете, что вам нужен только произвольный блок памяти, использование malloc и free вполне разумно.
Но если вы пишете код на C++, я думаю, что лучше использовать new/delete, так как вы будете использовать его для выделения объектов. Наличие двух типов функций выделения памяти добавляет больше путаницы. – Naveen
-1. new/delete - это языковые конструкции и вводят безопасность типов независимо от того, что вы выделяете/освобождаете. malloc/free - это артефакты, оставшиеся для обратной совместимости. – sharkin
@RA, если требуется произвольный общий блок байтов, нет никакой выгоды в том, чтобы полагать, что это особый символ char или unsigned или что-то еще - void * более честный и явный. +1 для malloc! –
Да, вы можете.
Но в зависимости от того, что вы делаете, могут быть лучшие приемы.
Можете ли вы обновить вопрос и рассказать нам, чего вы пытаетесь достичь. С большим контекстом может быть обеспечено лучшее решение.
Пример:
Если вы динамически выделяли буфер для чтения из сокета (поскольку размер не известен во время компиляции). Альтернативой будет использование векторного и динамического размера. Затем вы можете получить указатель на внутреннюю часть буфера, указав адрес первого элемента.
Лично я хотел бы использовать std::vector<char>
. Вы не только получаете произвольный блок байтов (guaranteed to be contiguous), вы получаете их в оболочке RAII.Конечно, нет необходимости использовать какие-либо из std::vector
«S методов (кроме, может быть, resize()
), но нет никакого штрафа за что:
std::vector<char> buffer(7);
void* p = &buffer[0];
Вы можете использовать std::string
, но std::string
означает«этот объект содержит символы, которые имеют смысл при распечатке », где« std::vector<char>
»подразумевает« этот объект содержит произвольную группу байтов ».
+1 для упоминания здесь * есть способ сделать это без malloc и free :) –
Также имейте в виду, что оператор new обычно просто передает доллар в malloc() в любом случае (на каждую реализацию, о которой я знаю). Как сказал Доминик, возможно, просто использовать malloc. –
Большое спасибо. Это ответ («:: operator new»). Я потратил много времени, пытаясь понять, почему «:: new (x)»; не работает :) – user132349