2012-03-05 17 views
7

Soy un principiante en C++, tengo el siguiente fragmento de código:C++: estructura y la nueva palabra clave

struct Airline { 
    string Name; 
    int diameter; 
    int weight; 
}; 

Airline* myPlane = new Airline; 

mi pregunta es cuando llamo el método new asigna memoria, si no recuerdo correctamente. ¿Cómo sabe la PC cuánta memoria asignar, especialmente teniendo en cuenta que hay un tipo de cadena allí?

Gracias

+0

mi conjetura, sin saber C++, es que almacena solo un puntero a la cadena, cuyos contenidos reales están en algún lugar en el montón. –

Respuesta

12

Un objeto std::string es de tamaño fijo; contiene un puntero a un búfer real de caracteres junto con su longitud. definición std::string 's se ve algo como

class string 
{ 
    char *buffer; 
    size_t nchars; 

    public: 
    // interface 
}; 

De ello se deduce que sus Airline objetos también tienen un tamaño fijo.

Ahora, new no solo asigna; también inicializa su objeto, incluido el std::string, lo que significa que probablemente establezca el puntero char en 0 porque la cadena está vacía.

+0

Gracias. Esto lo aclara. – Dan

0

Al asignar Airline, new va a asignar suficiente espacio en el montón de dos enteros, string y sus campos.

A string siempre tendrá el mismo tamaño en la pila. Sin embargo, internamente, el string almacena un puntero a una matriz de caracteres.

+0

Es posible que desee agregar * dónde * nuevas asignaciones y cómo la devolución de las nuevas se relaciona con esa ubicación. –

0

La memoria para la cadena puede o no estar dentro de la clase string. Posible (y probablemente), la clase string administrará su propia memoria, teniendo solo un puntero a la memoria utilizada para almacenar los datos. Ejemplo:

struct Airlane { 
    String Name { 
     char *data; // size = 4 
     size_t size; // size = 4 
    } 
    int diameter; // size = 4 
    int weight; // size = 4 
}; // size = 16 

Tenga en cuenta que esos no son necesariamente tamaños reales, son solo por ejemplo.

También tenga en cuenta que en C++ (a diferencia de C, por ejemplo), para cada class T, sizeof T es una constante de tiempo de compilación, lo que significa que los objetos nunca pueden tener tamaño dinámico. Esto significa en efecto: tan pronto como necesite datos de tamaño dinámico de tiempo de ejecución, tiene que haber áreas de memoria externas (por ejemplo, el objeto). Esto puede implicar el uso de contenedores estándar como std::string o std::vector, o incluso recursos gestionados manualmente.

Esto a su vez significa, operator new no necesita saber el tamaño dinámico de todos los miembros, de forma recursiva, pero sólo el tamaño de la clase más externa, la que se puede asignar. Cuando esta clase externa necesita más memoria, tiene que administrarla por sí misma. Algunos ejemplares de p-código:

Airline* myPlane = new Airline { 
    Name = { 
     data = new char[some-size] 
     ... 
    } 
    ... 
} 

Las asignaciones internas son realizadas por los constructores de retención:

Airline::Airline() : string(), ... {} 
string::string() : data(new char[...] ... {} 

operator new no hace más que asignar algo de memoria de tamaño fijo como el "suelo" de Airline (ver primer p-code), y luego "seeds" Airline s constructor, que a su vez tiene que administrar su tiempo de vida en ese volumen restringido de "suelo", invocando el constructor de cadenas (implícita o explícitamente), que hace otro new.

2

También puede obtener el tamaño de la estructura, mediante el uso de sizeof:

cout << "sizeof(Airline) = " << sizeof(Airline) << endl; 

Esto es debido a que el compilador sabe los campos dentro de la estructura, y la suma de los tamaños de cada miembro de estructura.

El objeto string no es diferente a su estructura. En realidad, es una clase en la biblioteca estándar, y no un tipo especial como int o float que maneja el compilador. Al igual que su estructura, la clase string contiene campos de los que el compilador conoce el tamaño, por lo que conoce el tamaño de la estructura completa y la usa cuando usa new.

2

La llamada a new asignará sizeof(Airline) que es lo que se necesita para contener un objeto de tipo Airline.

A partir de la gestión de cadenas, el objeto string contiene algunos datos internos para gestionar la memoria de los datos reales almacenados, pero no los datos en sí (a menos que se utilice la optimización de objetos pequeños). Si bien la idea es la misma que otros han apuntado con almacena un puntero a la cadena real, eso no es lo suficientemente preciso, ya que las implementaciones almacenarán ese puntero más los datos adicionales necesarios para contener size() y capacity() (y otros, como recuentos de referencia en implementaciones de recuento de referencias).

+0

explicación brillante. Muchas gracias. – Dan

Cuestiones relacionadas