Что использовать - «оператор новый» или «оператор новый []» - чтобы выделить блок необработанной памяти в C ++? - PullRequest
8 голосов
/ 23 марта 2010

Моей программе на C ++ нужен блок неинициализированной памяти и указатель void* на этот блок, чтобы я мог передать его сторонней библиотеке.Я хочу передать контроль над временем жизни блока в библиотеку, поэтому я не хочу использовать std::vector.Когда библиотека завершает работу с блоком, она вызывает обратный вызов, который я должен предоставить, и это освобождает блок.В CI будет использоваться malloc() и позже free().

. В C ++ я могу позвонить либо ::operator new, либо ::operator new[] и ::operator delete, либо operator delete[] соответственно:

void* newBlock = ::operator new( sizeOfBlock );
// then, later
::operator delete( newBlock );

Похоже, что и ::operator new, и ::operator new[] имеют абсолютно одинаковую подпись и абсолютно одинаковое поведение.То же самое для ::operator delete и ::operator delete[].Единственное, что я не должен делать, это связывать operator new с operator delete[] и наоборот - неопределенное поведение.Кроме той, какую пару я выбираю и почему?

Ответы [ 4 ]

7 голосов
/ 23 марта 2010

Используйте new с одним объектом и new[] с массивом объектов. Так, например:

int* x = new int; // Allocates single int
int* y = new int[5]; // Allocates an array of integers

*x = 10; // Assignment to single value
y[0] = 8; // Assignment to element of the array

Если все, что вы делаете, это выделение буфера памяти, то выделите массив char как в:

int bufferlen = /* choose a buffer size somehow */
char* buffer = new char[bufferlen];
// now can refer to buffer[0] ... buffer[bufferlen-1]

Однако в C ++ вы действительно должны использовать std::vector для произвольных массивов, и вы должны использовать std::string для символьных массивов, которые должны интерпретироваться или использоваться как строки.

Нет причин явно вызывать ::operator new или ::operator new[] вместо использования обычного синтаксиса для этих вызовов. Для типов POD и примитивов (например, char) инициализация не производится. Если вам нужно получить буфер void*, просто используйте static_cast для преобразования char* в void*.

1 голос
/ 23 марта 2010

На этот вопрос нельзя ответить разумно.

Во-первых, говорят, что программе «нужен» блок неинициализированной памяти, но из приведенного примера кода кажется, что программе «нужен» блокнеинициализированной и UNTYPED памяти, которая кажется не очень C ++ или OO.

Во-вторых, std :: vector дает единственный и автоматический контроль над блоком типизированной памяти, который может изменяться или не изменяться в размере в зависимости от его использования.Вы можете потерять этот элемент управления, если экземпляр std :: vector создается в куче и отслеживается с помощью необработанных указателей, как и для любого другого объекта C или C ++, такого как блок памяти void *.

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

1 голос
/ 23 марта 2010

Преимущество операторов C ++ new перед C * malloc() и free() состоит в том, что первый выдает исключение, если не хватает памяти, вместо того, чтобы возвращать NULL.

Что касается выбора нового (размера) и нового [] для буферов символов, я бы рекомендовал последний, поскольку менее вероятно удивить людей, поддерживающих код позже, т. Е. char* buf = new char[size] и delete[] buf.

Значения в буфере не будут инициализированы, и нет проверки диапазона - вам нужно создать хороший объект C ++, чтобы сделать это за вас, или использовать существующий объект, такой как std::vector или std::string.

0 голосов
/ 23 марта 2010

для выделения памяти массиву / списку используйте new [], кроме этого используйте new ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...