2009-07-02 29 views
8

¿Es posible asignar un bloque de memoria arbitrario con el operador "nuevo"? En C, puedo hacerlo como "void * p = malloc (7);" - Esto asignará 7 bytes si la alineación de memoria está configurada en 1 byte. ¿Cómo hacer lo mismo en C++ con el nuevo operador?asignación de memoria en C++

Respuesta

43

Los bloques de memoria arbitrarios se pueden asignar con operator new en C++; no con el operador new que es para construir objetos.

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

Tales bloques posteriormente pueden ser liberados con operator delete.

::operator delete(pBlock); 

Tenga en cuenta que operator new se asignan memoria convenientemente alineada para cualquier tipo de objeto, por lo que la aplicación podría no asignar exactamente siete bytes y no más, pero el mismo es (generalmente) de cierto malloc. Los clientes C de malloc generalmente también necesitan memoria alineada.

+7

+1 por mencionar allí * es * una forma de hacerlo sin malloc y gratis :) –

+1

Además, tenga en cuenta que el operador nuevo generalmente pasa el dinero a malloc() de todos modos (en cada implementación que conozco). Como dijo dominic, también podría usar malloc. –

+1

Muchas gracias. Esa es una respuesta (":: operador nuevo"). Pasé mucho tiempo intentando descubrir por qué el ":: nuevo (x);" no funciona :) – user132349

8

Usted no puede asignar un puntero void con el operador de C++ s new: tendrá que asignar un tipo explícito como char o uint8_t:

char *p = new char[7]; 
uint8_t *q = new uint8_t[7]; 
... 
delete [] p; 
delete [] q; 
2

Creo que podría estar buscando Placement New.

+1

Solo agregaría que si va a utilizar técnicas como la Colocación nueva, DEBE TENER CUIDADO. ¡Úselo solo si es realmente necesario! –

+5

¿Cómo se relaciona la ubicación nueva con la asignación de memoria? – avakar

+0

@Miky D: Estoy de acuerdo, por lo que la página vinculada está salpicada con la palabra "PELIGRO" en mayúsculas. :-) –

2

nuevo char [7];

Tradicionalmente, char es un byte, aunque puede encontrar algunas bibliotecas que typedef un tipo BYTE.

+5

No importa; un char es el tipo más pequeño que la implementación puede manejar. Si un char es de 16 bits, entonces un tipo de byte no puede ser inferior a 16 bits. Recuerde que sizeof (char) == 1. Siempre. –

+0

@David Thornley: sizeof (char) no es necesario 1, de lo contrario todo tipo de bibliotecas de clasificación se pondrán terriblemente molestos. – florin

+1

@florin: sizeof (char) == 1 según el estándar. Consulte la sección 5.3.3 de ISO/IEC 14882: 2003. "sizeof (char), sizeof (signed char) y sizeof (unsigned char) son 1; el resultado de sizeof aplicado a cualquier otro tipo fundamental (3.9.1) está definido por la implementación." –

2

Puede hacer char* pBuffer = new char[7];, y como el sizeof (char) es de 1 byte, puede usarlo como un búfer de bytes. Además, recuerde utilizar delete[] (con []) al liberar la memoria.

11

Otros han respondido la pregunta tal como está escrita, pero me gustaría sugerir que se quede con malloc/free para tales asignaciones.

new y delete son para asignar objetos. Asignan la memoria requerida y llaman a constructores/destructores. Si sabes que solo necesitas un bloque arbitrario de memoria, usar malloc y free es perfectamente razonable.

+1

Pero si está escribiendo código C++ creo que es mejor usar new/delete ya que lo usará para asignar los objetos. Tener dos tipos de funciones de asignación de memoria agrega más confusión. – Naveen

+1

-1. new/delete son construcciones de lenguaje e introducen seguridad tipo sin importar lo que asigne/desasigne. malloc/free son artefactos restantes por compatibilidad con versiones anteriores. – sharkin

+1

@RA, si uno necesita un bloque de bytes genérico arbitrario, no hay ganancia en hacer creer que son específicamente char o unsigned char o lo que sea - un vacío * es más honesto y explícito. +1 para malloc! –

3

Sí, puedes.
Pero dependiendo de lo que esté haciendo puede haber mejores técnicas.

Puede actualizar la pregunta y decirnos lo que está tratando de lograr. Con más contexto, se podría proporcionar una mejor solución.

Un ejemplo:
Si asignó dinámicamente un búfer para leer desde un socket (porque no se conoce el tamaño en tiempo de compilación). Una alternativa sería usar un vector y dimensionarlo dinámicamente. A continuación, puede obtener un puntero al interior del búfer al tomar la dirección del primer elemento.

3

Personalmente, utilizaría un std::vector<char>. No solo obtiene un bloque arbitrario de bytes (guaranteed to be contiguous), sino que los obtiene en un contenedor RAII.Por supuesto, no hay necesidad de utilizar cualquiera de std::vector 's métodos (aparte de, tal vez, resize()), pero no hay penalti que:

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

Se puede usar un std::string, pero std::string implica "este objeto contiene caracteres que tienen sentido cuando se imprimen, "donde un std::vector<char> implica que" este objeto contiene un grupo arbitrario de bytes ".

Cuestiones relacionadas